@bongos/core 1.19.358 → 1.19.360
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 +64 -24
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +20 -0
- package/clients/bongos-client/index.cjs +20 -0
- package/clients/bongos-client/index.d.ts +30 -0
- package/clients/bongos-client/index.mjs +20 -0
- package/docs/api/openapi.json +512 -3
- package/docs/api-reference.md +20 -2
- package/modules/builder-settings/builder-needs.js +29 -2
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +20 -0
- package/modules/lifecycle/closeness-weights.json +64 -0
- package/modules/lifecycle/closeness.js +363 -0
- package/modules/lifecycle/lifecycle.js +5 -0
- package/modules/lifecycle/migrations/lifecycle_005_task_recommendations.sql +90 -0
- package/modules/lifecycle/module.json +2 -0
- package/modules/lifecycle/routes/closeness.js +118 -0
- package/modules/lifecycle/routes/recommendations.js +148 -0
- package/modules/lifecycle/task-recommendations.js +247 -0
- package/modules/platform-identity/platform-identity.js +28 -0
- package/modules/platform-identity/routes/sso.js +4 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/src/bongos/routes/me.js +15 -0
- package/src/module-api.js +5 -1
- package/tests/closeness.mjs +324 -0
- package/tests/task_recommendations.mjs +297 -0
package/docs/api/openapi.json
CHANGED
|
@@ -73,6 +73,10 @@
|
|
|
73
73
|
"name": "claims",
|
|
74
74
|
"description": "Endpoints under `/api/bongos/claims`."
|
|
75
75
|
},
|
|
76
|
+
{
|
|
77
|
+
"name": "closeness",
|
|
78
|
+
"description": "Endpoints under `/api/bongos/closeness`."
|
|
79
|
+
},
|
|
76
80
|
{
|
|
77
81
|
"name": "copy-desk",
|
|
78
82
|
"description": "Endpoints under `/api/bongos/copy-desk`."
|
|
@@ -205,6 +209,10 @@
|
|
|
205
209
|
"name": "sso",
|
|
206
210
|
"description": "Endpoints under `/api/bongos/sso`."
|
|
207
211
|
},
|
|
212
|
+
{
|
|
213
|
+
"name": "task-recommendations",
|
|
214
|
+
"description": "Endpoints under `/api/bongos/task-recommendations`."
|
|
215
|
+
},
|
|
208
216
|
{
|
|
209
217
|
"name": "task-visuals",
|
|
210
218
|
"description": "Endpoints under `/api/bongos/task-visuals`."
|
|
@@ -3191,6 +3199,134 @@
|
|
|
3191
3199
|
]
|
|
3192
3200
|
}
|
|
3193
3201
|
},
|
|
3202
|
+
"/closeness/for-me": {
|
|
3203
|
+
"get": {
|
|
3204
|
+
"operationId": "get_closeness_for_me",
|
|
3205
|
+
"tags": [
|
|
3206
|
+
"closeness"
|
|
3207
|
+
],
|
|
3208
|
+
"summary": "GET /closeness/for-me",
|
|
3209
|
+
"description": ", and OWN-SCOPED — your own graph, never someone else's. Reading another builder's graph would expose who THEY are close to, which is a fact about third parties they did not consent to share.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
3210
|
+
"x-rank": "any-builder",
|
|
3211
|
+
"x-source": "modules/lifecycle/routes/closeness.js",
|
|
3212
|
+
"responses": {
|
|
3213
|
+
"200": {
|
|
3214
|
+
"description": "Success.",
|
|
3215
|
+
"content": {
|
|
3216
|
+
"application/json": {
|
|
3217
|
+
"schema": {
|
|
3218
|
+
"$ref": "#/components/schemas/GetClosenessForMeResponse"
|
|
3219
|
+
}
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
},
|
|
3223
|
+
"400": {
|
|
3224
|
+
"$ref": "#/components/responses/BadRequest"
|
|
3225
|
+
},
|
|
3226
|
+
"401": {
|
|
3227
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
3228
|
+
},
|
|
3229
|
+
"403": {
|
|
3230
|
+
"$ref": "#/components/responses/Forbidden"
|
|
3231
|
+
}
|
|
3232
|
+
},
|
|
3233
|
+
"security": [
|
|
3234
|
+
{
|
|
3235
|
+
"builderSession": []
|
|
3236
|
+
}
|
|
3237
|
+
]
|
|
3238
|
+
}
|
|
3239
|
+
},
|
|
3240
|
+
"/closeness/weights": {
|
|
3241
|
+
"get": {
|
|
3242
|
+
"operationId": "get_closeness_weights",
|
|
3243
|
+
"tags": [
|
|
3244
|
+
"closeness"
|
|
3245
|
+
],
|
|
3246
|
+
"summary": "GET /closeness/weights",
|
|
3247
|
+
"description": "the MODEL is not private, and publishing it is the whole point of the weights being data. It describes how the system scores people; a builder ranked by it is entitled to read it.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
3248
|
+
"x-rank": "any-builder",
|
|
3249
|
+
"x-source": "modules/lifecycle/routes/closeness.js",
|
|
3250
|
+
"responses": {
|
|
3251
|
+
"200": {
|
|
3252
|
+
"description": "Success.",
|
|
3253
|
+
"content": {
|
|
3254
|
+
"application/json": {
|
|
3255
|
+
"schema": {
|
|
3256
|
+
"$ref": "#/components/schemas/GetClosenessWeightsResponse"
|
|
3257
|
+
}
|
|
3258
|
+
}
|
|
3259
|
+
}
|
|
3260
|
+
},
|
|
3261
|
+
"400": {
|
|
3262
|
+
"$ref": "#/components/responses/BadRequest"
|
|
3263
|
+
},
|
|
3264
|
+
"401": {
|
|
3265
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
3266
|
+
},
|
|
3267
|
+
"403": {
|
|
3268
|
+
"$ref": "#/components/responses/Forbidden"
|
|
3269
|
+
}
|
|
3270
|
+
},
|
|
3271
|
+
"security": [
|
|
3272
|
+
{
|
|
3273
|
+
"builderSession": []
|
|
3274
|
+
}
|
|
3275
|
+
]
|
|
3276
|
+
}
|
|
3277
|
+
},
|
|
3278
|
+
"/closeness/with/{builderId}": {
|
|
3279
|
+
"get": {
|
|
3280
|
+
"operationId": "get_closeness_with_builderId",
|
|
3281
|
+
"tags": [
|
|
3282
|
+
"closeness"
|
|
3283
|
+
],
|
|
3284
|
+
"summary": "GET /closeness/with/:builderId",
|
|
3285
|
+
"description": "One pair — \"why am I close to THEM\", asked directly rather than by paging the graph. Always relative to the CALLER: the pair is (you, them). rank: any-builder.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
3286
|
+
"x-rank": "any-builder",
|
|
3287
|
+
"x-source": "modules/lifecycle/routes/closeness.js",
|
|
3288
|
+
"parameters": [
|
|
3289
|
+
{
|
|
3290
|
+
"name": "builderId",
|
|
3291
|
+
"in": "path",
|
|
3292
|
+
"required": true,
|
|
3293
|
+
"schema": {
|
|
3294
|
+
"type": "string"
|
|
3295
|
+
},
|
|
3296
|
+
"description": "Path parameter `builderId`."
|
|
3297
|
+
}
|
|
3298
|
+
],
|
|
3299
|
+
"responses": {
|
|
3300
|
+
"200": {
|
|
3301
|
+
"description": "Success.",
|
|
3302
|
+
"content": {
|
|
3303
|
+
"application/json": {
|
|
3304
|
+
"schema": {
|
|
3305
|
+
"$ref": "#/components/schemas/GetClosenessWithBuilderIdResponse"
|
|
3306
|
+
}
|
|
3307
|
+
}
|
|
3308
|
+
}
|
|
3309
|
+
},
|
|
3310
|
+
"400": {
|
|
3311
|
+
"$ref": "#/components/responses/BadRequest"
|
|
3312
|
+
},
|
|
3313
|
+
"401": {
|
|
3314
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
3315
|
+
},
|
|
3316
|
+
"403": {
|
|
3317
|
+
"$ref": "#/components/responses/Forbidden"
|
|
3318
|
+
},
|
|
3319
|
+
"404": {
|
|
3320
|
+
"$ref": "#/components/responses/NotFound"
|
|
3321
|
+
}
|
|
3322
|
+
},
|
|
3323
|
+
"security": [
|
|
3324
|
+
{
|
|
3325
|
+
"builderSession": []
|
|
3326
|
+
}
|
|
3327
|
+
]
|
|
3328
|
+
}
|
|
3329
|
+
},
|
|
3194
3330
|
"/copy-desk/flags": {
|
|
3195
3331
|
"post": {
|
|
3196
3332
|
"operationId": "post_copy_desk_flags",
|
|
@@ -12092,6 +12228,194 @@
|
|
|
12092
12228
|
"security": []
|
|
12093
12229
|
}
|
|
12094
12230
|
},
|
|
12231
|
+
"/task-recommendations": {
|
|
12232
|
+
"post": {
|
|
12233
|
+
"operationId": "post_task_recommendations",
|
|
12234
|
+
"tags": [
|
|
12235
|
+
"task-recommendations"
|
|
12236
|
+
],
|
|
12237
|
+
"summary": "POST /task-recommendations",
|
|
12238
|
+
"description": "recommending is not a privileged act. It grants the recipient nothing they did not already have (the task was claimable by them or it was not), so gating it by rank would only stop newcomers from pointing at something useful.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
12239
|
+
"x-rank": "any-builder",
|
|
12240
|
+
"x-source": "modules/lifecycle/routes/recommendations.js",
|
|
12241
|
+
"requestBody": {
|
|
12242
|
+
"required": true,
|
|
12243
|
+
"content": {
|
|
12244
|
+
"application/json": {
|
|
12245
|
+
"schema": {
|
|
12246
|
+
"$ref": "#/components/schemas/PostTaskRecommendationsRequest"
|
|
12247
|
+
}
|
|
12248
|
+
}
|
|
12249
|
+
},
|
|
12250
|
+
"x-validated": true
|
|
12251
|
+
},
|
|
12252
|
+
"responses": {
|
|
12253
|
+
"200": {
|
|
12254
|
+
"description": "Success.",
|
|
12255
|
+
"content": {
|
|
12256
|
+
"application/json": {
|
|
12257
|
+
"schema": {
|
|
12258
|
+
"$ref": "#/components/schemas/PostTaskRecommendationsResponse"
|
|
12259
|
+
}
|
|
12260
|
+
}
|
|
12261
|
+
}
|
|
12262
|
+
},
|
|
12263
|
+
"400": {
|
|
12264
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
12265
|
+
},
|
|
12266
|
+
"401": {
|
|
12267
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
12268
|
+
},
|
|
12269
|
+
"403": {
|
|
12270
|
+
"$ref": "#/components/responses/Forbidden"
|
|
12271
|
+
}
|
|
12272
|
+
},
|
|
12273
|
+
"security": [
|
|
12274
|
+
{
|
|
12275
|
+
"builderSession": []
|
|
12276
|
+
}
|
|
12277
|
+
]
|
|
12278
|
+
}
|
|
12279
|
+
},
|
|
12280
|
+
"/task-recommendations/for-me": {
|
|
12281
|
+
"get": {
|
|
12282
|
+
"operationId": "get_task_recommendations_for_me",
|
|
12283
|
+
"tags": [
|
|
12284
|
+
"task-recommendations"
|
|
12285
|
+
],
|
|
12286
|
+
"summary": "GET /task-recommendations/for-me",
|
|
12287
|
+
"description": "you only ever see what is addressed to you. NOTE WHAT THIS RESPONSE DOES NOT CONTAIN: any signal that the recipient now holds the task. It carries the task's own status so the recipient can judge, and that is all. Claiming is a separate, deliberate act on their part.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
12288
|
+
"x-rank": "any-builder",
|
|
12289
|
+
"x-source": "modules/lifecycle/routes/recommendations.js",
|
|
12290
|
+
"responses": {
|
|
12291
|
+
"200": {
|
|
12292
|
+
"description": "Success.",
|
|
12293
|
+
"content": {
|
|
12294
|
+
"application/json": {
|
|
12295
|
+
"schema": {
|
|
12296
|
+
"$ref": "#/components/schemas/GetTaskRecommendationsForMeResponse"
|
|
12297
|
+
}
|
|
12298
|
+
}
|
|
12299
|
+
}
|
|
12300
|
+
},
|
|
12301
|
+
"400": {
|
|
12302
|
+
"$ref": "#/components/responses/BadRequest"
|
|
12303
|
+
},
|
|
12304
|
+
"401": {
|
|
12305
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
12306
|
+
},
|
|
12307
|
+
"403": {
|
|
12308
|
+
"$ref": "#/components/responses/Forbidden"
|
|
12309
|
+
}
|
|
12310
|
+
},
|
|
12311
|
+
"security": [
|
|
12312
|
+
{
|
|
12313
|
+
"builderSession": []
|
|
12314
|
+
}
|
|
12315
|
+
]
|
|
12316
|
+
}
|
|
12317
|
+
},
|
|
12318
|
+
"/task-recommendations/mine": {
|
|
12319
|
+
"get": {
|
|
12320
|
+
"operationId": "get_task_recommendations_mine",
|
|
12321
|
+
"tags": [
|
|
12322
|
+
"task-recommendations"
|
|
12323
|
+
],
|
|
12324
|
+
"summary": "GET /task-recommendations/mine",
|
|
12325
|
+
"description": "what I recommended, and what became of it. Unfiltered by default: a declined recommendation stays readable, which is the criterion's \"the recommendation and its author are readable afterwards\".\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
12326
|
+
"x-rank": "any-builder",
|
|
12327
|
+
"x-source": "modules/lifecycle/routes/recommendations.js",
|
|
12328
|
+
"responses": {
|
|
12329
|
+
"200": {
|
|
12330
|
+
"description": "Success.",
|
|
12331
|
+
"content": {
|
|
12332
|
+
"application/json": {
|
|
12333
|
+
"schema": {
|
|
12334
|
+
"$ref": "#/components/schemas/GetTaskRecommendationsMineResponse"
|
|
12335
|
+
}
|
|
12336
|
+
}
|
|
12337
|
+
}
|
|
12338
|
+
},
|
|
12339
|
+
"400": {
|
|
12340
|
+
"$ref": "#/components/responses/BadRequest"
|
|
12341
|
+
},
|
|
12342
|
+
"401": {
|
|
12343
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
12344
|
+
},
|
|
12345
|
+
"403": {
|
|
12346
|
+
"$ref": "#/components/responses/Forbidden"
|
|
12347
|
+
}
|
|
12348
|
+
},
|
|
12349
|
+
"security": [
|
|
12350
|
+
{
|
|
12351
|
+
"builderSession": []
|
|
12352
|
+
}
|
|
12353
|
+
]
|
|
12354
|
+
}
|
|
12355
|
+
},
|
|
12356
|
+
"/task-recommendations/{id}": {
|
|
12357
|
+
"patch": {
|
|
12358
|
+
"operationId": "patch_task_recommendations_id",
|
|
12359
|
+
"tags": [
|
|
12360
|
+
"task-recommendations"
|
|
12361
|
+
],
|
|
12362
|
+
"summary": "PATCH /task-recommendations/:id",
|
|
12363
|
+
"description": "Decline. Costs nothing, and this route is where that is visible: it flips a status and returns the row. No karma call, no counter, no notification to the sender beyond the row itself turning up in their own list. rank: any-builder — ownership is enforced in the UPDATE's WHERE, not by rank.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
12364
|
+
"x-rank": "any-builder",
|
|
12365
|
+
"x-source": "modules/lifecycle/routes/recommendations.js",
|
|
12366
|
+
"parameters": [
|
|
12367
|
+
{
|
|
12368
|
+
"name": "id",
|
|
12369
|
+
"in": "path",
|
|
12370
|
+
"required": true,
|
|
12371
|
+
"schema": {
|
|
12372
|
+
"type": "string"
|
|
12373
|
+
},
|
|
12374
|
+
"description": "Path parameter `id`."
|
|
12375
|
+
}
|
|
12376
|
+
],
|
|
12377
|
+
"requestBody": {
|
|
12378
|
+
"required": true,
|
|
12379
|
+
"content": {
|
|
12380
|
+
"application/json": {
|
|
12381
|
+
"schema": {
|
|
12382
|
+
"$ref": "#/components/schemas/PatchTaskRecommendationsIdRequest"
|
|
12383
|
+
}
|
|
12384
|
+
}
|
|
12385
|
+
},
|
|
12386
|
+
"x-validated": true
|
|
12387
|
+
},
|
|
12388
|
+
"responses": {
|
|
12389
|
+
"200": {
|
|
12390
|
+
"description": "Success.",
|
|
12391
|
+
"content": {
|
|
12392
|
+
"application/json": {
|
|
12393
|
+
"schema": {
|
|
12394
|
+
"$ref": "#/components/schemas/PatchTaskRecommendationsIdResponse"
|
|
12395
|
+
}
|
|
12396
|
+
}
|
|
12397
|
+
}
|
|
12398
|
+
},
|
|
12399
|
+
"400": {
|
|
12400
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
12401
|
+
},
|
|
12402
|
+
"401": {
|
|
12403
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
12404
|
+
},
|
|
12405
|
+
"403": {
|
|
12406
|
+
"$ref": "#/components/responses/Forbidden"
|
|
12407
|
+
},
|
|
12408
|
+
"404": {
|
|
12409
|
+
"$ref": "#/components/responses/NotFound"
|
|
12410
|
+
}
|
|
12411
|
+
},
|
|
12412
|
+
"security": [
|
|
12413
|
+
{
|
|
12414
|
+
"builderSession": []
|
|
12415
|
+
}
|
|
12416
|
+
]
|
|
12417
|
+
}
|
|
12418
|
+
},
|
|
12095
12419
|
"/task-visuals/{name}": {
|
|
12096
12420
|
"get": {
|
|
12097
12421
|
"operationId": "get_task_visuals_name",
|
|
@@ -13431,6 +13755,58 @@
|
|
|
13431
13755
|
]
|
|
13432
13756
|
}
|
|
13433
13757
|
},
|
|
13758
|
+
"/tasks/{id}/recommendations": {
|
|
13759
|
+
"get": {
|
|
13760
|
+
"operationId": "get_tasks_id_recommendations",
|
|
13761
|
+
"tags": [
|
|
13762
|
+
"tasks"
|
|
13763
|
+
],
|
|
13764
|
+
"summary": "GET /tasks/:id/recommendations",
|
|
13765
|
+
"description": "The per-task audit read: who recommended this task, to whom, and why. rank: any-builder, and deliberately NOT scoped to the two parties. The criterion's argument for a ledger is that an untraced recommendation is indistinguishable from a task quietly changing hands — a trace only the two people involved can read does not answer that. Tasks are already visible to every builder, and a recommendation says nothing more private than \"this person thought that person should look at this\".\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
13766
|
+
"x-rank": "any-builder",
|
|
13767
|
+
"x-source": "modules/lifecycle/routes/recommendations.js",
|
|
13768
|
+
"parameters": [
|
|
13769
|
+
{
|
|
13770
|
+
"name": "id",
|
|
13771
|
+
"in": "path",
|
|
13772
|
+
"required": true,
|
|
13773
|
+
"schema": {
|
|
13774
|
+
"type": "string"
|
|
13775
|
+
},
|
|
13776
|
+
"description": "Path parameter `id`."
|
|
13777
|
+
}
|
|
13778
|
+
],
|
|
13779
|
+
"responses": {
|
|
13780
|
+
"200": {
|
|
13781
|
+
"description": "Success.",
|
|
13782
|
+
"content": {
|
|
13783
|
+
"application/json": {
|
|
13784
|
+
"schema": {
|
|
13785
|
+
"$ref": "#/components/schemas/GetTasksIdRecommendationsResponse"
|
|
13786
|
+
}
|
|
13787
|
+
}
|
|
13788
|
+
}
|
|
13789
|
+
},
|
|
13790
|
+
"400": {
|
|
13791
|
+
"$ref": "#/components/responses/BadRequest"
|
|
13792
|
+
},
|
|
13793
|
+
"401": {
|
|
13794
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
13795
|
+
},
|
|
13796
|
+
"403": {
|
|
13797
|
+
"$ref": "#/components/responses/Forbidden"
|
|
13798
|
+
},
|
|
13799
|
+
"404": {
|
|
13800
|
+
"$ref": "#/components/responses/NotFound"
|
|
13801
|
+
}
|
|
13802
|
+
},
|
|
13803
|
+
"security": [
|
|
13804
|
+
{
|
|
13805
|
+
"builderSession": []
|
|
13806
|
+
}
|
|
13807
|
+
]
|
|
13808
|
+
}
|
|
13809
|
+
},
|
|
13434
13810
|
"/tasks/{id}/ship": {
|
|
13435
13811
|
"post": {
|
|
13436
13812
|
"operationId": "post_tasks_id_ship",
|
|
@@ -14376,6 +14752,41 @@
|
|
|
14376
14752
|
"stale_hours"
|
|
14377
14753
|
]
|
|
14378
14754
|
},
|
|
14755
|
+
"GetClosenessForMeResponse": {
|
|
14756
|
+
"type": "object",
|
|
14757
|
+
"properties": {
|
|
14758
|
+
"closeness": {},
|
|
14759
|
+
"count": {}
|
|
14760
|
+
},
|
|
14761
|
+
"required": [
|
|
14762
|
+
"closeness",
|
|
14763
|
+
"count"
|
|
14764
|
+
]
|
|
14765
|
+
},
|
|
14766
|
+
"GetClosenessWeightsResponse": {
|
|
14767
|
+
"type": "object",
|
|
14768
|
+
"properties": {
|
|
14769
|
+
"weights": {},
|
|
14770
|
+
"window_days": {},
|
|
14771
|
+
"note": {}
|
|
14772
|
+
},
|
|
14773
|
+
"required": [
|
|
14774
|
+
"weights",
|
|
14775
|
+
"window_days",
|
|
14776
|
+
"note"
|
|
14777
|
+
]
|
|
14778
|
+
},
|
|
14779
|
+
"GetClosenessWithBuilderIdResponse": {
|
|
14780
|
+
"type": "object",
|
|
14781
|
+
"properties": {
|
|
14782
|
+
"closeness": {},
|
|
14783
|
+
"why": {}
|
|
14784
|
+
},
|
|
14785
|
+
"required": [
|
|
14786
|
+
"closeness",
|
|
14787
|
+
"why"
|
|
14788
|
+
]
|
|
14789
|
+
},
|
|
14379
14790
|
"GetDiscordChannelsPlanResponse": {
|
|
14380
14791
|
"type": "object",
|
|
14381
14792
|
"properties": {
|
|
@@ -15307,6 +15718,28 @@
|
|
|
15307
15718
|
"public_key_b64"
|
|
15308
15719
|
]
|
|
15309
15720
|
},
|
|
15721
|
+
"GetTaskRecommendationsForMeResponse": {
|
|
15722
|
+
"type": "object",
|
|
15723
|
+
"properties": {
|
|
15724
|
+
"recommendations": {},
|
|
15725
|
+
"count": {}
|
|
15726
|
+
},
|
|
15727
|
+
"required": [
|
|
15728
|
+
"recommendations",
|
|
15729
|
+
"count"
|
|
15730
|
+
]
|
|
15731
|
+
},
|
|
15732
|
+
"GetTaskRecommendationsMineResponse": {
|
|
15733
|
+
"type": "object",
|
|
15734
|
+
"properties": {
|
|
15735
|
+
"recommendations": {},
|
|
15736
|
+
"count": {}
|
|
15737
|
+
},
|
|
15738
|
+
"required": [
|
|
15739
|
+
"recommendations",
|
|
15740
|
+
"count"
|
|
15741
|
+
]
|
|
15742
|
+
},
|
|
15310
15743
|
"GetTasksClaimableResponse": {
|
|
15311
15744
|
"type": "object",
|
|
15312
15745
|
"properties": {
|
|
@@ -15338,6 +15771,17 @@
|
|
|
15338
15771
|
"dependents"
|
|
15339
15772
|
]
|
|
15340
15773
|
},
|
|
15774
|
+
"GetTasksIdRecommendationsResponse": {
|
|
15775
|
+
"type": "object",
|
|
15776
|
+
"properties": {
|
|
15777
|
+
"recommendations": {},
|
|
15778
|
+
"count": {}
|
|
15779
|
+
},
|
|
15780
|
+
"required": [
|
|
15781
|
+
"recommendations",
|
|
15782
|
+
"count"
|
|
15783
|
+
]
|
|
15784
|
+
},
|
|
15341
15785
|
"GetTasksNewcomerFloorResponse": {
|
|
15342
15786
|
"type": "object",
|
|
15343
15787
|
"properties": {
|
|
@@ -15925,6 +16369,35 @@
|
|
|
15925
16369
|
"push"
|
|
15926
16370
|
]
|
|
15927
16371
|
},
|
|
16372
|
+
"PatchTaskRecommendationsIdRequest": {
|
|
16373
|
+
"type": "object",
|
|
16374
|
+
"properties": {
|
|
16375
|
+
"status": {
|
|
16376
|
+
"type": "string",
|
|
16377
|
+
"enum": [
|
|
16378
|
+
"declined",
|
|
16379
|
+
"withdrawn"
|
|
16380
|
+
]
|
|
16381
|
+
}
|
|
16382
|
+
},
|
|
16383
|
+
"required": [
|
|
16384
|
+
"status"
|
|
16385
|
+
],
|
|
16386
|
+
"additionalProperties": false
|
|
16387
|
+
},
|
|
16388
|
+
"PatchTaskRecommendationsIdResponse": {
|
|
16389
|
+
"type": "object",
|
|
16390
|
+
"properties": {
|
|
16391
|
+
"ok": {
|
|
16392
|
+
"type": "boolean"
|
|
16393
|
+
},
|
|
16394
|
+
"recommendation": {}
|
|
16395
|
+
},
|
|
16396
|
+
"required": [
|
|
16397
|
+
"ok",
|
|
16398
|
+
"recommendation"
|
|
16399
|
+
]
|
|
16400
|
+
},
|
|
15928
16401
|
"PatchTasksIdRequest": {
|
|
15929
16402
|
"type": "object",
|
|
15930
16403
|
"properties": {
|
|
@@ -18777,6 +19250,42 @@
|
|
|
18777
19250
|
"avatar_url"
|
|
18778
19251
|
]
|
|
18779
19252
|
},
|
|
19253
|
+
"PostTaskRecommendationsRequest": {
|
|
19254
|
+
"type": "object",
|
|
19255
|
+
"properties": {
|
|
19256
|
+
"task_id": {
|
|
19257
|
+
"type": "integer",
|
|
19258
|
+
"minimum": 1
|
|
19259
|
+
},
|
|
19260
|
+
"recommended_to": {
|
|
19261
|
+
"type": "integer",
|
|
19262
|
+
"minimum": 1
|
|
19263
|
+
},
|
|
19264
|
+
"reason": {
|
|
19265
|
+
"type": "string",
|
|
19266
|
+
"minLength": 1
|
|
19267
|
+
}
|
|
19268
|
+
},
|
|
19269
|
+
"required": [
|
|
19270
|
+
"task_id",
|
|
19271
|
+
"recommended_to",
|
|
19272
|
+
"reason"
|
|
19273
|
+
],
|
|
19274
|
+
"additionalProperties": false
|
|
19275
|
+
},
|
|
19276
|
+
"PostTaskRecommendationsResponse": {
|
|
19277
|
+
"type": "object",
|
|
19278
|
+
"properties": {
|
|
19279
|
+
"ok": {
|
|
19280
|
+
"type": "boolean"
|
|
19281
|
+
},
|
|
19282
|
+
"recommendation": {}
|
|
19283
|
+
},
|
|
19284
|
+
"required": [
|
|
19285
|
+
"ok",
|
|
19286
|
+
"recommendation"
|
|
19287
|
+
]
|
|
19288
|
+
},
|
|
18780
19289
|
"PostTasksIdAbandonRequest": {
|
|
18781
19290
|
"type": "object",
|
|
18782
19291
|
"properties": {
|
|
@@ -19452,9 +19961,9 @@
|
|
|
19452
19961
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
19453
19962
|
}
|
|
19454
19963
|
},
|
|
19455
|
-
"x-endpoint-count":
|
|
19456
|
-
"x-schema-count":
|
|
19964
|
+
"x-endpoint-count": 315,
|
|
19965
|
+
"x-schema-count": 353,
|
|
19457
19966
|
"x-undocumented-bodies": 8,
|
|
19458
|
-
"x-response-schemas":
|
|
19967
|
+
"x-response-schemas": 237,
|
|
19459
19968
|
"x-generated-by": "scripts/gds/gen-api-docs.js"
|
|
19460
19969
|
}
|
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. 315 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`.
|
|
@@ -143,6 +143,14 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
143
143
|
| POST | `/api/bongos/claims/batch/release` | `any-builder` | `claim_ids`, `force` | Bulk release (task 1758) — the batch twin of resolve(outcome='abandoned'). |
|
|
144
144
|
| POST | `/api/bongos/claims/batch/validate` | `any-builder` | `task_ids` | Dry-run validate (task 1758) — read-only twin of claimTasksBatch's pre-flight checks. |
|
|
145
145
|
|
|
146
|
+
## `closeness` (3)
|
|
147
|
+
|
|
148
|
+
| Method | Path | Rank | Body | Description |
|
|
149
|
+
|---|---|---|---|---|
|
|
150
|
+
| GET | `/api/bongos/closeness/for-me` | `any-builder` | — | , and OWN-SCOPED — your own graph, never someone else's. |
|
|
151
|
+
| GET | `/api/bongos/closeness/weights` | `any-builder` | — | the MODEL is not private, and publishing it is the whole point of the weights being data. |
|
|
152
|
+
| GET | `/api/bongos/closeness/with/:builderId` | `any-builder` | — | One pair — "why am I close to THEM", asked directly rather than by paging the graph. |
|
|
153
|
+
|
|
146
154
|
## `copy-desk` (4)
|
|
147
155
|
|
|
148
156
|
| Method | Path | Rank | Body | Description |
|
|
@@ -507,13 +515,22 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
507
515
|
| GET | `/api/bongos/sso/pubkey` | `public` | — | GET /sso/pubkey — the hub's Ed25519 assertion-verification key (public). |
|
|
508
516
|
| POST | `/api/bongos/sso/token` | `public` | `client_id`, `client_secret`, `code`, `redirect_uri` | POST /sso/token — server-to-server code redemption. |
|
|
509
517
|
|
|
518
|
+
## `task-recommendations` (4)
|
|
519
|
+
|
|
520
|
+
| Method | Path | Rank | Body | Description |
|
|
521
|
+
|---|---|---|---|---|
|
|
522
|
+
| POST | `/api/bongos/task-recommendations` | `any-builder` | `task_id`, `recommended_to`, `reason` | recommending is not a privileged act. |
|
|
523
|
+
| PATCH | `/api/bongos/task-recommendations/:id` | `any-builder` | `status` | Decline. |
|
|
524
|
+
| GET | `/api/bongos/task-recommendations/for-me` | `any-builder` | — | you only ever see what is addressed to you. |
|
|
525
|
+
| GET | `/api/bongos/task-recommendations/mine` | `any-builder` | — | what I recommended, and what became of it. |
|
|
526
|
+
|
|
510
527
|
## `task-visuals` (1)
|
|
511
528
|
|
|
512
529
|
| Method | Path | Rank | Body | Description |
|
|
513
530
|
|---|---|---|---|---|
|
|
514
531
|
| GET | `/api/bongos/task-visuals/:name` | `public` | — | the WIDEST path this route can take, declared honestly. |
|
|
515
532
|
|
|
516
|
-
## `tasks` (
|
|
533
|
+
## `tasks` (30)
|
|
517
534
|
|
|
518
535
|
| Method | Path | Rank | Body | Description |
|
|
519
536
|
|---|---|---|---|---|
|
|
@@ -537,6 +554,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
537
554
|
| POST | `/api/bongos/tasks/:id/promote` | `metic+archon` | — | backlog→ready promotion; scope mutation; ADR 0090 (was archon). |
|
|
538
555
|
| POST | `/api/bongos/tasks/:id/publish-branch` | `any-builder` | `branch`, `head_sha`, `bundle_b64`, `value_summary` | |
|
|
539
556
|
| GET | `/api/bongos/tasks/:id/publish-status` | `any-builder` | — | GET /tasks/:id/publish-status?branch=<branch> — poll the PR + prod-deploy state for a server-mediated publish so ship.js can confirm the … |
|
|
557
|
+
| GET | `/api/bongos/tasks/:id/recommendations` | `any-builder` | — | The per-task audit read: who recommended this task, to whom, and why. |
|
|
540
558
|
| POST | `/api/bongos/tasks/:id/ship` | `any-builder` | validated | confirmed → shipped. |
|
|
541
559
|
| POST | `/api/bongos/tasks/:id/visual` | `any-builder` | `image_b64`, `content_type`, `alt` | POST /tasks/:id/visual — attach (or replace) this task's ship-time visual. |
|
|
542
560
|
| DELETE | `/api/bongos/tasks/:id/visual` | `any-builder` | — | DELETE /tasks/:id/visual — remove it again. |
|
|
@@ -121,7 +121,34 @@ function helpRequestsNeed(ctx) {
|
|
|
121
121
|
|
|
122
122
|
// The registry. To add a future input the system needs from a builder, append a
|
|
123
123
|
// pure (ctx) => need|null function here — every renderer picks it up for free.
|
|
124
|
-
|
|
124
|
+
// Open task RECOMMENDATIONS waiting on this builder (task 1003173 / C03, goal
|
|
125
|
+
// 1000075; criterion collab-pass-a-task). Sibling of helpRequestsNeed above, and
|
|
126
|
+
// here for the same reason C01's grader round put that one here: a recommendation
|
|
127
|
+
// nobody surfaces is merely stored, and the criterion's whole argument is that a
|
|
128
|
+
// recommendation must be a visible, traceable judgement rather than a task
|
|
129
|
+
// quietly changing hands.
|
|
130
|
+
//
|
|
131
|
+
// 'info', NOT a demand, and the message says so. A recommendation grants the
|
|
132
|
+
// recipient nothing and obliges them to nothing — they still claim it themselves
|
|
133
|
+
// if they want it, and declining costs nothing (ADR 0187 §3). Wording that
|
|
134
|
+
// pressured the reader would BE the penalty the decision forbids.
|
|
135
|
+
function taskRecommendationsNeed(ctx) {
|
|
136
|
+
const n = Number(ctx.openTaskRecommendations) || 0;
|
|
137
|
+
if (n <= 0) return null;
|
|
138
|
+
const subject = n === 1 ? 'A task' : `${n} tasks`;
|
|
139
|
+
const verb = n === 1 ? 'was' : 'were';
|
|
140
|
+
return {
|
|
141
|
+
id: 'task_recommendations',
|
|
142
|
+
title: n === 1 ? 'Someone recommended a task to you' : 'Tasks were recommended to you',
|
|
143
|
+
what: 'Another builder thought you should look at a task, and said why. It is a suggestion, not an assignment.',
|
|
144
|
+
state: 'action_needed',
|
|
145
|
+
severity: 'info',
|
|
146
|
+
message: `${subject} ${verb} recommended to you. Nothing has been assigned — you would still claim it yourself, and declining costs nothing.`,
|
|
147
|
+
action: { label: n === 1 ? 'See the recommendation' : 'See the recommendations', href: '/#/collab' },
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
const NEEDS = [artKeyNeed, helpRequestsNeed, taskRecommendationsNeed];
|
|
125
152
|
|
|
126
153
|
// ---- founding grace (task 1002739 / direction §5.6, idea 1000701) -----------
|
|
127
154
|
//
|
|
@@ -199,7 +226,7 @@ module.exports = {
|
|
|
199
226
|
computeNeeds,
|
|
200
227
|
// exported for tests / direct reuse
|
|
201
228
|
artKeyNeed,
|
|
202
|
-
helpRequestsNeed,
|
|
229
|
+
helpRequestsNeed, taskRecommendationsNeed,
|
|
203
230
|
foundingGraceActive,
|
|
204
231
|
FOUNDING_GRACE_DAYS,
|
|
205
232
|
SETTINGS_PATH,
|