@bongos/core 1.20.21 → 1.20.23
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 +78 -48
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +4 -2
- package/clients/bongos-client/index.cjs +4 -2
- package/clients/bongos-client/index.d.ts +8 -4
- package/clients/bongos-client/index.mjs +4 -2
- package/docs/adr/0335-an-invite-is-a-pre-approved-row-on-the-projects-own-instance.md +1 -0
- package/docs/adr/0353-a-hub-invite-is-a-notice-of-the-projects-own-invite.md +70 -0
- package/docs/adr/README.md +1 -0
- package/docs/api/openapi.json +137 -72
- package/docs/api-reference.md +6 -5
- package/docs/architecture.md +14 -0
- package/docs/copy-inventory.md +196 -196
- package/docs/copy-registry.json +250 -250
- package/docs/module-api-changelog.md +4 -0
- package/docs/page-inventory.json +2 -1
- package/docs/page-readings.json +310 -306
- package/migrations/core_265_module_assessments.sql +97 -0
- package/modules/hall-ui/public/watch.js +23 -0
- package/modules/onboarding/routes/access-requests.js +36 -6
- package/modules/platform-identity/invite-notices.js +61 -0
- package/modules/platform-identity/module.json +1 -1
- package/modules/platform-identity/platform-identity.js +12 -18
- package/modules/platform-identity/routes/my-projects.js +6 -15
- package/modules/platform-identity/routes/projects.js +22 -15
- package/modules/platform-identity/routes/sso-invites.js +82 -0
- package/modules/platform-identity/tests/platform-identity.mjs +14 -11
- package/modules/public-landing/public/assets/cosmos.css +5 -0
- package/modules/public-landing/public/projects.html +35 -29
- package/modules/public-landing/public/projects.states.json +1 -0
- package/modules/ui-design/kit/serve.js +9 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/release-notes.json +12 -0
- package/src/bongos/auth-admission.js +40 -0
- package/src/bongos/auth.js +2 -1
- package/src/module-api.js +8 -1
- package/tests/access_requests_invite.mjs +39 -1
- package/tests/application_lifecycle.mjs +41 -1
- package/tests/catalog_only_client.mjs +5 -3
- package/tests/hub_invite_notices.mjs +261 -0
- package/tests/module_api.mjs +1 -0
- package/tests/module_assessments_migration.mjs +96 -0
- package/tests/my_projects_surface.mjs +11 -1
- package/tests/project_invite_ownership.mjs +12 -7
- package/tests/project_invite_ui.mjs +42 -45
- package/tests/watch_applications_queue.mjs +33 -2
package/docs/adr/README.md
CHANGED
|
@@ -471,3 +471,4 @@ These 20 numbers are each shared by exactly two files. They are **accepted histo
|
|
|
471
471
|
| 0350 | [**The hub holds a per-project WRITE deploy key, so a hosted project's upgraded pin always reaches its GitHub repo** ([task 1004291](https://cloudbongos.com/builders#/task/1004291), follow-up to task 1004065). Amends ADR 0176. The owner's token lasts one hour and the checkout's own key is read-only, so most hosted upgrades ended "GitHub was not updated". **D1:** a second deploy key per repo, registered `read_only: false` as `cloudbongos-pin-<slug>`, the pull key untouched. **D2:** kept outside every checkout in the runner's own directory (0700 dir, 0600 key, modes verified), unreadable by the project's account. **D3:** minted at standup and whenever a fresh owner token finds none, so reconnecting GitHub once is enough. **D4:** `pushUpgradePin` tries write key, then owner token, then origin, never forced. **D5:** revoked on teardown and disconnect. **D6:** a project on the shared app user is refused a key: "needs its own account first". **D7:** /deploy says reconnecting sets up lasting access.](0350-the-hub-holds-a-per-project-write-deploy-key-so-a-hosted-upgrade-reaches-github.md) | provisioning / security |
|
|
472
472
|
| 0351 | [**A criterion closes on a UAT, not on its linked tasks shipping** ([task 1004392](https://cloudbongos.com/builders#/task/1004392), goal 1000089 — working area 3). Supersedes ADR 0183's close rule. `wa7-government` had closed on six Board Room navigation tasks while nothing it describes was on the live site. **D1:** three checks — Code (linked tasks done, ≥1 shipped; automatic), Live, UAT — and the sweep closes a criterion only with a CURRENT sign-off (no older than the newest linked ship). **D2 (owner):** "Awaiting UAT" is a visible state. **D3 (owner):** one step; the signer is refused if they shipped linked work, the project owner excepted. **D4 (owner):** an mp4/webm up to 100 MB on the project's own server. **D5 (owner):** backend-only is set while a criterion is open and takes a recording-free sign-off. **D6 (owner):** Live is read via the `deploy.taskWhere` port where the site can tell, attested otherwise. **D7 (owner):** already-closed criteria stay closed ("Closed before UAT"). **D8:** `/satisfy` is a recorded override that needs a reason. **D9:** `/goal-uat` + `scripts/gds/uat.js`; the hall is task 1004402.](0351-a-criterion-closes-on-a-uat.md) | lifecycle / criteria / review |
|
|
473
473
|
| 0352 | [**A rollup report carries its "as of" in a header, and the hub keeps the newest** ([task 1004268](https://cloudbongos.com/builders#/task/1004268), goal 1000110). `POST /sso/activity/rollup` was last-writer-wins with no report timestamp, so a sign-in push read earlier and a ship push read later could land the older totals last. **D1:** the instance's read time rides a `Bongos-Report-As-Of` HEADER, not a body field, because the hub validates the body strictly and hub and instances upgrade independently: a body field from a newer instance would 400 on an older hub and lose the report, while an unknown header is ignored. **D2:** missing or unparseable = unstamped = last-writer-wins, never a 400. **D3:** the guard is a WHERE on the upsert's conflict branch (migration 026, `reported_as_of`, no backfill); a skipped update keeps the row lock, so the task 1004244 snapshot stays in step. **D4:** the stamp is compared only with the same client's, and clamped to the hub's `now()`.](0352-a-rollup-report-carries-its-as-of-in-a-header.md) | platform identity / federation |
|
|
474
|
+
| 0353 | [**A hub invite is a notice of the project's own invite, and signing in accepts it** ([task 1002818](https://cloudbongos.com/builders#/task/1002818), goal 1000110 — R6 of the admin console wave). The hub's own invite wrote a `pending` membership that no project reads, so an "accepted" invite met a locked door (new projects default to `apply`). **D1:** that row is now a NOTICE the PROJECT writes: its invite route calls `POST /sso/invites/notify` and a dismissal that leaves no invited row calls `/sso/invites/clear` (client credentials, pending rows only, always `{ ok: true }` so no account oracle); core's `notifyHubOfInvite` is fire-and-forget. **D2:** the hub-side accept route is deleted; signing in to the project accepts, and the hub's own sign-in witness turns the row into a membership. **D3 (owner):** `POST /projects/invite` writes nothing and answers `{ invited: false, invite_url }`, the project's hall invite link (`/builders/watch?invite=<login>`, which only pre-fills); the signed-assertion relay is deferred. **D4:** new routes, so an older hub 404s and only the notice is lost (ADR 0352).](0353-a-hub-invite-is-a-notice-of-the-projects-own-invite.md) | platform identity / federation |
|
package/docs/api/openapi.json
CHANGED
|
@@ -388,7 +388,7 @@
|
|
|
388
388
|
"access-requests"
|
|
389
389
|
],
|
|
390
390
|
"summary": "POST /access-requests/invite",
|
|
391
|
-
"description": "POST /access-requests/invite — an Archon admits a GitHub username BEFORE any request exists (task 1003044): the only way in on an invite-only project, where the public POST refuses, and a shortcut on an apply one. It writes the same access_request row the sign-in gate reads (status 'invited' — hasInvitedAccessRequest), so nothing new is consulted at sign-in; a pending request for that login is resolved in place rather than duplicated. Two Archons inviting the same login at once can each insert a row (the unique index covers pending only): harmless — the gate reads \"any invited row\" — and it shows as two lines in the invited history, so no lock is taken. A fresh row is marked kind='invite' with created_by = the sender (a rescind overwrites resolved_by) and the optional note as the inviter's words. A pending request resolved in place stays an application with its applicant's own note (ADR 0335 D2.1–D2.3; task 1002814). body: { github_login, note? }. 201 with a new row; 200 with the row when a pending request was resolved; 200 already_invited when an invite already stands; 409 already_member when they have an account. rank: archon — the same gate as resolving a request.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `access_request.review` (all required).",
|
|
391
|
+
"description": "POST /access-requests/invite — an Archon admits a GitHub username BEFORE any request exists (task 1003044): the only way in on an invite-only project, where the public POST refuses, and a shortcut on an apply one. It writes the same access_request row the sign-in gate reads (status 'invited' — hasInvitedAccessRequest), so nothing new is consulted at sign-in; a pending request for that login is resolved in place rather than duplicated. Two Archons inviting the same login at once can each insert a row (the unique index covers pending only): harmless — the gate reads \"any invited row\" — and it shows as two lines in the invited history, so no lock is taken. A fresh row is marked kind='invite' with created_by = the sender (a rescind overwrites resolved_by) and the optional note as the inviter's words. A pending request resolved in place stays an application with its applicant's own note (ADR 0335 D2.1–D2.3; task 1002814). Every outcome that leaves the login invited also notifies the hub, so the invitee sees it in My Projects (ADR 0353). body: { github_login, note? }. 201 with a new row; 200 with the row when a pending request was resolved; 200 already_invited when an invite already stands; 409 already_member when they have an account. rank: archon — the same gate as resolving a request.\n\n**Rank:** `archon` — Archon only (rank and identity management + the escalation keys — the trust boundary).\n\n**Permissions:** `access_request.review` (all required).",
|
|
392
392
|
"x-rank": "archon",
|
|
393
393
|
"x-source": "modules/onboarding/routes/access-requests.js",
|
|
394
394
|
"x-permissions": [
|
|
@@ -13194,58 +13194,6 @@
|
|
|
13194
13194
|
]
|
|
13195
13195
|
}
|
|
13196
13196
|
},
|
|
13197
|
-
"/my-projects/invites/{clientId}/accept": {
|
|
13198
|
-
"post": {
|
|
13199
|
-
"operationId": "post_my_projects_invites_clientId_accept",
|
|
13200
|
-
"tags": [
|
|
13201
|
-
"my-projects"
|
|
13202
|
-
],
|
|
13203
|
-
"summary": "POST /my-projects/invites/:clientId/accept",
|
|
13204
|
-
"description": "accept an invite (pending → builder) for the caller's OWN account.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
13205
|
-
"x-rank": "any-builder",
|
|
13206
|
-
"x-source": "modules/platform-identity/routes/my-projects.js",
|
|
13207
|
-
"parameters": [
|
|
13208
|
-
{
|
|
13209
|
-
"name": "clientId",
|
|
13210
|
-
"in": "path",
|
|
13211
|
-
"required": true,
|
|
13212
|
-
"schema": {
|
|
13213
|
-
"type": "string"
|
|
13214
|
-
},
|
|
13215
|
-
"description": "Path parameter `clientId`."
|
|
13216
|
-
}
|
|
13217
|
-
],
|
|
13218
|
-
"responses": {
|
|
13219
|
-
"200": {
|
|
13220
|
-
"description": "Success.",
|
|
13221
|
-
"content": {
|
|
13222
|
-
"application/json": {
|
|
13223
|
-
"schema": {
|
|
13224
|
-
"$ref": "#/components/schemas/PostMyProjectsInvitesClientIdAcceptResponse"
|
|
13225
|
-
}
|
|
13226
|
-
}
|
|
13227
|
-
}
|
|
13228
|
-
},
|
|
13229
|
-
"400": {
|
|
13230
|
-
"$ref": "#/components/responses/BadRequest"
|
|
13231
|
-
},
|
|
13232
|
-
"401": {
|
|
13233
|
-
"$ref": "#/components/responses/Unauthorized"
|
|
13234
|
-
},
|
|
13235
|
-
"403": {
|
|
13236
|
-
"$ref": "#/components/responses/Forbidden"
|
|
13237
|
-
},
|
|
13238
|
-
"404": {
|
|
13239
|
-
"$ref": "#/components/responses/NotFound"
|
|
13240
|
-
}
|
|
13241
|
-
},
|
|
13242
|
-
"security": [
|
|
13243
|
-
{
|
|
13244
|
-
"builderSession": []
|
|
13245
|
-
}
|
|
13246
|
-
]
|
|
13247
|
-
}
|
|
13248
|
-
},
|
|
13249
13197
|
"/my-projects/invites/{clientId}/decline": {
|
|
13250
13198
|
"post": {
|
|
13251
13199
|
"operationId": "post_my_projects_invites_clientId_decline",
|
|
@@ -14001,7 +13949,7 @@
|
|
|
14001
13949
|
"projects"
|
|
14002
13950
|
],
|
|
14003
13951
|
"summary": "POST /projects/invite",
|
|
14004
|
-
"description": "own-or-metic in effect: invite a builder into a project
|
|
13952
|
+
"description": "own-or-metic in effect: where to invite a builder into a project, asked by a `project.curate` holder OR the project's OWN OWNER (task 1003580; the ownership proof is `provisioning_instances.owner_builder_id`, reached through a port — see invite-authz.js). The wizard's audience is any signed-in GitHub user, typically a xenos who used to get 403 on their own project. A caller who is neither gets the unchanged permission refusal, identical whether or not the project exists. IT WRITES NOTHING (task 1002818, ADR 0353). It used to pre-seed a 'pending' hub membership, but the hub holds no verdict: that row let nobody in, and on any door but `open` (new projects default to `apply`) the invitee who signed in met a locked door. Only the project's own invite admits (ADR 0335 D1/D2), so the answer is 200 `{ invited: false, invite_url }` — the project's hall invite box with the login pre-filled. A 200, not a refusal: it is the answer every admitted caller gets, and a 4xx on the normal path would log a failed request in the owner's browser on every invite. Sending it there also reaches this hub: the project notifies it (POST /sso/invites/notify), and the invitee sees it in My Projects.\n\n**Rank:** `metic+archon` — Metic or Archon rank (review/triage powers).\n\n**Permissions:** `project.curate` (all required).",
|
|
14005
13953
|
"x-rank": "metic+archon",
|
|
14006
13954
|
"x-source": "modules/platform-identity/routes/projects.js",
|
|
14007
13955
|
"x-permissions": [
|
|
@@ -14020,7 +13968,14 @@
|
|
|
14020
13968
|
},
|
|
14021
13969
|
"responses": {
|
|
14022
13970
|
"200": {
|
|
14023
|
-
"description": "Success."
|
|
13971
|
+
"description": "Success.",
|
|
13972
|
+
"content": {
|
|
13973
|
+
"application/json": {
|
|
13974
|
+
"schema": {
|
|
13975
|
+
"$ref": "#/components/schemas/PostProjectsInviteResponse"
|
|
13976
|
+
}
|
|
13977
|
+
}
|
|
13978
|
+
}
|
|
14024
13979
|
},
|
|
14025
13980
|
"400": {
|
|
14026
13981
|
"$ref": "#/components/responses/ValidationFailed"
|
|
@@ -18684,6 +18639,70 @@
|
|
|
18684
18639
|
"security": []
|
|
18685
18640
|
}
|
|
18686
18641
|
},
|
|
18642
|
+
"/sso/invites/clear": {
|
|
18643
|
+
"post": {
|
|
18644
|
+
"operationId": "post_sso_invites_clear",
|
|
18645
|
+
"tags": [
|
|
18646
|
+
"sso"
|
|
18647
|
+
],
|
|
18648
|
+
"summary": "POST /sso/invites/clear",
|
|
18649
|
+
"description": "authenticated by client_id + client_secret, not a builder rank.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
18650
|
+
"x-rank": "public",
|
|
18651
|
+
"x-source": "modules/platform-identity/routes/sso-invites.js",
|
|
18652
|
+
"requestBody": {
|
|
18653
|
+
"required": true,
|
|
18654
|
+
"content": {
|
|
18655
|
+
"application/json": {
|
|
18656
|
+
"schema": {
|
|
18657
|
+
"$ref": "#/components/schemas/PostSsoInvitesClearRequest"
|
|
18658
|
+
}
|
|
18659
|
+
}
|
|
18660
|
+
},
|
|
18661
|
+
"x-validated": true
|
|
18662
|
+
},
|
|
18663
|
+
"responses": {
|
|
18664
|
+
"200": {
|
|
18665
|
+
"description": "Success."
|
|
18666
|
+
},
|
|
18667
|
+
"400": {
|
|
18668
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
18669
|
+
}
|
|
18670
|
+
},
|
|
18671
|
+
"security": []
|
|
18672
|
+
}
|
|
18673
|
+
},
|
|
18674
|
+
"/sso/invites/notify": {
|
|
18675
|
+
"post": {
|
|
18676
|
+
"operationId": "post_sso_invites_notify",
|
|
18677
|
+
"tags": [
|
|
18678
|
+
"sso"
|
|
18679
|
+
],
|
|
18680
|
+
"summary": "POST /sso/invites/notify",
|
|
18681
|
+
"description": "authenticated by client_id + client_secret, not a builder rank.\n\n**Rank:** `public` — No authentication — any caller.",
|
|
18682
|
+
"x-rank": "public",
|
|
18683
|
+
"x-source": "modules/platform-identity/routes/sso-invites.js",
|
|
18684
|
+
"requestBody": {
|
|
18685
|
+
"required": true,
|
|
18686
|
+
"content": {
|
|
18687
|
+
"application/json": {
|
|
18688
|
+
"schema": {
|
|
18689
|
+
"$ref": "#/components/schemas/PostSsoInvitesNotifyRequest"
|
|
18690
|
+
}
|
|
18691
|
+
}
|
|
18692
|
+
},
|
|
18693
|
+
"x-validated": true
|
|
18694
|
+
},
|
|
18695
|
+
"responses": {
|
|
18696
|
+
"200": {
|
|
18697
|
+
"description": "Success."
|
|
18698
|
+
},
|
|
18699
|
+
"400": {
|
|
18700
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
18701
|
+
}
|
|
18702
|
+
},
|
|
18703
|
+
"security": []
|
|
18704
|
+
}
|
|
18705
|
+
},
|
|
18687
18706
|
"/sso/membership/check-in": {
|
|
18688
18707
|
"post": {
|
|
18689
18708
|
"operationId": "post_sso_membership_check_in",
|
|
@@ -27289,21 +27308,6 @@
|
|
|
27289
27308
|
"left"
|
|
27290
27309
|
]
|
|
27291
27310
|
},
|
|
27292
|
-
"PostMyProjectsInvitesClientIdAcceptResponse": {
|
|
27293
|
-
"type": "object",
|
|
27294
|
-
"properties": {
|
|
27295
|
-
"ok": {
|
|
27296
|
-
"type": "boolean"
|
|
27297
|
-
},
|
|
27298
|
-
"accepted": {
|
|
27299
|
-
"type": "boolean"
|
|
27300
|
-
}
|
|
27301
|
-
},
|
|
27302
|
-
"required": [
|
|
27303
|
-
"ok",
|
|
27304
|
-
"accepted"
|
|
27305
|
-
]
|
|
27306
|
-
},
|
|
27307
27311
|
"PostMyProjectsInvitesClientIdDeclineResponse": {
|
|
27308
27312
|
"type": "object",
|
|
27309
27313
|
"properties": {
|
|
@@ -27400,6 +27404,19 @@
|
|
|
27400
27404
|
],
|
|
27401
27405
|
"additionalProperties": false
|
|
27402
27406
|
},
|
|
27407
|
+
"PostProjectsInviteResponse": {
|
|
27408
|
+
"type": "object",
|
|
27409
|
+
"properties": {
|
|
27410
|
+
"invited": {
|
|
27411
|
+
"type": "boolean"
|
|
27412
|
+
},
|
|
27413
|
+
"invite_url": {}
|
|
27414
|
+
},
|
|
27415
|
+
"required": [
|
|
27416
|
+
"invited",
|
|
27417
|
+
"invite_url"
|
|
27418
|
+
]
|
|
27419
|
+
},
|
|
27403
27420
|
"PostProjectsProjectIdSpecialitiesRequest": {
|
|
27404
27421
|
"type": "object",
|
|
27405
27422
|
"properties": {
|
|
@@ -28452,6 +28469,54 @@
|
|
|
28452
28469
|
],
|
|
28453
28470
|
"additionalProperties": false
|
|
28454
28471
|
},
|
|
28472
|
+
"PostSsoInvitesClearRequest": {
|
|
28473
|
+
"type": "object",
|
|
28474
|
+
"properties": {
|
|
28475
|
+
"client_id": {
|
|
28476
|
+
"type": "string",
|
|
28477
|
+
"maxLength": 200
|
|
28478
|
+
},
|
|
28479
|
+
"client_secret": {
|
|
28480
|
+
"type": "string",
|
|
28481
|
+
"maxLength": 512
|
|
28482
|
+
},
|
|
28483
|
+
"github_login": {
|
|
28484
|
+
"type": "string",
|
|
28485
|
+
"minLength": 1,
|
|
28486
|
+
"maxLength": 200
|
|
28487
|
+
}
|
|
28488
|
+
},
|
|
28489
|
+
"required": [
|
|
28490
|
+
"client_id",
|
|
28491
|
+
"client_secret",
|
|
28492
|
+
"github_login"
|
|
28493
|
+
],
|
|
28494
|
+
"additionalProperties": false
|
|
28495
|
+
},
|
|
28496
|
+
"PostSsoInvitesNotifyRequest": {
|
|
28497
|
+
"type": "object",
|
|
28498
|
+
"properties": {
|
|
28499
|
+
"client_id": {
|
|
28500
|
+
"type": "string",
|
|
28501
|
+
"maxLength": 200
|
|
28502
|
+
},
|
|
28503
|
+
"client_secret": {
|
|
28504
|
+
"type": "string",
|
|
28505
|
+
"maxLength": 512
|
|
28506
|
+
},
|
|
28507
|
+
"github_login": {
|
|
28508
|
+
"type": "string",
|
|
28509
|
+
"minLength": 1,
|
|
28510
|
+
"maxLength": 200
|
|
28511
|
+
}
|
|
28512
|
+
},
|
|
28513
|
+
"required": [
|
|
28514
|
+
"client_id",
|
|
28515
|
+
"client_secret",
|
|
28516
|
+
"github_login"
|
|
28517
|
+
],
|
|
28518
|
+
"additionalProperties": false
|
|
28519
|
+
},
|
|
28455
28520
|
"PostSsoMembershipCheckInRequest": {
|
|
28456
28521
|
"type": "object",
|
|
28457
28522
|
"properties": {
|
|
@@ -29564,8 +29629,8 @@
|
|
|
29564
29629
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
29565
29630
|
}
|
|
29566
29631
|
},
|
|
29567
|
-
"x-endpoint-count":
|
|
29568
|
-
"x-schema-count":
|
|
29632
|
+
"x-endpoint-count": 463,
|
|
29633
|
+
"x-schema-count": 496,
|
|
29569
29634
|
"x-undocumented-bodies": 12,
|
|
29570
29635
|
"x-response-schemas": 336,
|
|
29571
29636
|
"x-generated-by": "scripts/gds/gen-api-docs.js"
|
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. 463 endpoints across 83 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`.
|
|
@@ -506,14 +506,13 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
506
506
|
| POST | `/api/bongos/modules/:key/submit` | `metic+archon` | `signed_by` | POST /api/bongos/modules/:key/submit — ADR 0107 §1 upstreaming submission. |
|
|
507
507
|
| GET | `/api/bongos/modules/submissions` | `metic+archon` | — | GET /api/bongos/modules/submissions?status=&module_key= — the upstreaming review queue (task 1771 reads this). |
|
|
508
508
|
|
|
509
|
-
## `my-projects` (
|
|
509
|
+
## `my-projects` (5)
|
|
510
510
|
|
|
511
511
|
| Method | Path | Rank | Body | Description |
|
|
512
512
|
|---|---|---|---|---|
|
|
513
513
|
| GET | `/api/bongos/my-projects` | `any-builder` | — | the caller's OWN cross-project memberships (own data). |
|
|
514
514
|
| POST | `/api/bongos/my-projects/:clientId/leave` | `any-builder` | — | leave a project from the caller's OWN membership list. |
|
|
515
515
|
| GET | `/api/bongos/my-projects/invites` | `any-builder` | — | the caller's OWN pending invitations (ADR 0141 §5). |
|
|
516
|
-
| POST | `/api/bongos/my-projects/invites/:clientId/accept` | `any-builder` | — | accept an invite (pending → builder) for the caller's OWN account. |
|
|
517
516
|
| POST | `/api/bongos/my-projects/invites/:clientId/decline` | `any-builder` | — | decline an invite (delete the pending row) for the caller's OWN account. |
|
|
518
517
|
| POST | `/api/bongos/my-projects/join` | `any-builder` | `origin`, `note` | request to join a project. |
|
|
519
518
|
|
|
@@ -559,7 +558,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
559
558
|
| PATCH | `/api/bongos/projects/:id/status` | `metic+archon` | `status` | THE TAKEDOWN LEVER (R08, task 1002327; ADR 0252 §5.1). |
|
|
560
559
|
| POST | `/api/bongos/projects/:projectId/specialities` | `any-builder` | `name`, `discipline`, `summary`, `contract_md`, `visibility`, `sellable`, `skills` | POST /projects/:projectId/specialities — author one OWNED BY A PROJECT. |
|
|
561
560
|
| GET | `/api/bongos/projects/featured` | `public` | — | the public map of projects; no auth by design. |
|
|
562
|
-
| POST | `/api/bongos/projects/invite` | `metic+archon` | `client_id`, `github_login` | own-or-metic in effect: invite a builder into a project
|
|
561
|
+
| POST | `/api/bongos/projects/invite` | `metic+archon` | `client_id`, `github_login` | own-or-metic in effect: where to invite a builder into a project, asked by a `project.curate` holder OR the project's OWN OWNER (task 100… |
|
|
563
562
|
|
|
564
563
|
## `provisioning` (34)
|
|
565
564
|
|
|
@@ -719,7 +718,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
719
718
|
| GET | `/api/bongos/specialities/installed-skills` | `any-builder` | — | GET /specialities/installed-skills — every skill THIS instance has, each explained the way the adoption walkthrough explains it, so a spe… |
|
|
720
719
|
| GET | `/api/bongos/specialities/offered` | `any-builder` | — | GET /specialities/offered — the suggestions for THIS builder. |
|
|
721
720
|
|
|
722
|
-
## `sso` (
|
|
721
|
+
## `sso` (10)
|
|
723
722
|
|
|
724
723
|
| Method | Path | Rank | Body | Description |
|
|
725
724
|
|---|---|---|---|---|
|
|
@@ -728,6 +727,8 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/0016-trust
|
|
|
728
727
|
| GET | `/api/bongos/sso/authorize` | `public` | — | GET /sso/authorize?client_id=&redirect_uri=&state= — the browser authorize leg. |
|
|
729
728
|
| POST | `/api/bongos/sso/device/poll` | `public` | `device_code` | POST /sso/device/poll — poll the hub device flow. |
|
|
730
729
|
| POST | `/api/bongos/sso/device/start` | `public` | `origin` | POST /sso/device/start — begin CLI federation. |
|
|
730
|
+
| POST | `/api/bongos/sso/invites/clear` | `public` | `client_id`, `client_secret`, `github_login` | authenticated by client_id + client_secret, not a builder rank. |
|
|
731
|
+
| POST | `/api/bongos/sso/invites/notify` | `public` | `client_id`, `client_secret`, `github_login` | authenticated by client_id + client_secret, not a builder rank. |
|
|
731
732
|
| POST | `/api/bongos/sso/membership/check-in` | `public` | `client_id`, `client_secret`, `github_id`, `github_login`, `display_name`, `avatar_url`, `membership_kind` | POST /sso/membership/check-in — a federated instance reports, on every sign-in, that a builder builds on its project (ADR 0141 §3). |
|
|
732
733
|
| GET | `/api/bongos/sso/pubkey` | `public` | — | GET /sso/pubkey — the hub's Ed25519 assertion-verification key (public). |
|
|
733
734
|
| POST | `/api/bongos/sso/token` | `public` | `client_id`, `client_secret`, `code`, `redirect_uri` | POST /sso/token — server-to-server code redemption. |
|
package/docs/architecture.md
CHANGED
|
@@ -258,6 +258,20 @@ module_entitlements(id, module_key, holder_kind IN (builder|instance), holder_re
|
|
|
258
258
|
-- keeping the row.
|
|
259
259
|
```
|
|
260
260
|
|
|
261
|
+
Module assessments (migration `core_265`, task 1003814 — [ADR 0343](adr/0343-a-module-score-is-a-security-gate-then-an-average-of-visible-parts.md) + [ADR 0347](adr/0347-every-store-module-ships-a-how-to.md) D5; per module VERSION, append-only history, the current row is the newest; never reads price):
|
|
262
|
+
|
|
263
|
+
```
|
|
264
|
+
module_assessment_signals(id, version_id → store_module_versions, part IN (security|tests|
|
|
265
|
+
install|reliability|tester_feedback|docs), outcome IN (scored|passed|failed|
|
|
266
|
+
no_data|pending|not_scored), score 0-100 iff scored, sample_size, reason,
|
|
267
|
+
detail jsonb, measured_at) -- security is pass/fail only (the D2 gate);
|
|
268
|
+
-- "no data yet" is an outcome, never a zero (D3/D5)
|
|
269
|
+
module_assessment_scores(id, version_id, kind IN (computed|override), overall 0-100 | NULL,
|
|
270
|
+
security_passed, is_new (D5 "New" label), formula, signal_ids bigint[],
|
|
271
|
+
override_by, override_reason, computed_at) -- an override names who + why
|
|
272
|
+
-- and is a new row on the computed history, never an edit (D6)
|
|
273
|
+
```
|
|
274
|
+
|
|
261
275
|
Code: `src/bongos/module-entitlements.js` (`grantEntitlement`, `recordAcquired`, `revokeEntitlement`, `checkEntitlement`, `listEntitlements`). Read routes (own-scoped, `requireBuilder`): `GET /store/entitlements`, `GET /store/modules/:key/entitlement`. Install (task 1003785) grants a free module through `POST /store/modules/:key/acquire`; the buy action (area 8) will grant a paid one.
|
|
262
276
|
|
|
263
277
|
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).
|