@bongos/core 1.19.59 → 1.19.61
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 +37 -22
- package/clients/bongos-client/README.md +1 -1
- package/clients/bongos-client/bongos-client.global.js +2 -0
- package/clients/bongos-client/index.cjs +2 -0
- package/clients/bongos-client/index.d.ts +6 -2
- package/clients/bongos-client/index.mjs +2 -0
- package/docs/api/openapi.json +104 -3
- package/docs/api-reference.md +3 -2
- package/modules/dev-box/app/src/vendor/bongos-client.cjs +2 -0
- package/modules/provisioning/migrations/provisioning_005_domain_attach.sql +20 -0
- package/modules/provisioning/provisioning.js +67 -5
- package/modules/provisioning/routes/provisioning.js +126 -12
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/provision.js +92 -4
- package/src/module-api.js +5 -1
- package/tests/provision.mjs +134 -0
- package/tests/provisioning_domain_attach.mjs +289 -0
- package/tests/provisioning_teardown_intent.mjs +267 -0
package/.bongos-core.json
CHANGED
|
@@ -2,22 +2,22 @@
|
|
|
2
2
|
"artifact": "bongos-core",
|
|
3
3
|
"manifest_schema": 1,
|
|
4
4
|
"generator": "scripts/gds/package-core.js",
|
|
5
|
-
"core_version": "1.19.
|
|
6
|
-
"core_contract": "1.19.
|
|
7
|
-
"source_commit": "
|
|
5
|
+
"core_version": "1.19.61",
|
|
6
|
+
"core_contract": "1.19.61",
|
|
7
|
+
"source_commit": "073b10995781fbdfae0a9da943fa8755002e51bf",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-
|
|
9
|
+
"built_at": "2026-08-12T00:24:52.611Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 291,
|
|
13
13
|
"agent_docs_stubbed": 21,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 1220,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 1532,
|
|
20
|
+
"tree_sha256": "c4d2ff9c96e88bf23e2c2c1acf1593d174589a1b9beeb7b3b12d61c65bb84113",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -347,12 +347,12 @@
|
|
|
347
347
|
{
|
|
348
348
|
"path": "clients/bongos-client/README.md",
|
|
349
349
|
"mode": "0000644",
|
|
350
|
-
"sha256": "
|
|
350
|
+
"sha256": "36eb537043097dc8e05307adc06d893a2c5ceb8cceb63f24b64ade001a0a2640"
|
|
351
351
|
},
|
|
352
352
|
{
|
|
353
353
|
"path": "clients/bongos-client/bongos-client.global.js",
|
|
354
354
|
"mode": "0000644",
|
|
355
|
-
"sha256": "
|
|
355
|
+
"sha256": "ad598bf38511e3e7bd9f25a82987126cd71cfe76ac8275ddee2bcd90eb8e6a11"
|
|
356
356
|
},
|
|
357
357
|
{
|
|
358
358
|
"path": "clients/bongos-client/examples/hello-world.mjs",
|
|
@@ -362,17 +362,17 @@
|
|
|
362
362
|
{
|
|
363
363
|
"path": "clients/bongos-client/index.cjs",
|
|
364
364
|
"mode": "0000644",
|
|
365
|
-
"sha256": "
|
|
365
|
+
"sha256": "43823273ec587b104f3e0296614ae8ea6c4dc5c96261dbbb359ae39c21cf4e79"
|
|
366
366
|
},
|
|
367
367
|
{
|
|
368
368
|
"path": "clients/bongos-client/index.d.ts",
|
|
369
369
|
"mode": "0000644",
|
|
370
|
-
"sha256": "
|
|
370
|
+
"sha256": "4deeae55ba58483557310d768a63df7cd75a1219137539b7ccbbf4481f09f5d9"
|
|
371
371
|
},
|
|
372
372
|
{
|
|
373
373
|
"path": "clients/bongos-client/index.mjs",
|
|
374
374
|
"mode": "0000644",
|
|
375
|
-
"sha256": "
|
|
375
|
+
"sha256": "6d441799f948513f840394bd382dba7e601e79a07fb7591bcb0e05aea2edd2a9"
|
|
376
376
|
},
|
|
377
377
|
{
|
|
378
378
|
"path": "clients/bongos-client/package.json",
|
|
@@ -1307,12 +1307,12 @@
|
|
|
1307
1307
|
{
|
|
1308
1308
|
"path": "docs/api-reference.md",
|
|
1309
1309
|
"mode": "0000644",
|
|
1310
|
-
"sha256": "
|
|
1310
|
+
"sha256": "a30007778606ce90b8e31470d926047a372c72b93022f54023937cfd4c5b5fc0"
|
|
1311
1311
|
},
|
|
1312
1312
|
{
|
|
1313
1313
|
"path": "docs/api/openapi.json",
|
|
1314
1314
|
"mode": "0000644",
|
|
1315
|
-
"sha256": "
|
|
1315
|
+
"sha256": "0e7646ee148453ef5d6d51b3434253b76f35628ee6c36681dbf6e7b27dd20c6f"
|
|
1316
1316
|
},
|
|
1317
1317
|
{
|
|
1318
1318
|
"path": "docs/architecture.md",
|
|
@@ -2552,7 +2552,7 @@
|
|
|
2552
2552
|
{
|
|
2553
2553
|
"path": "modules/dev-box/app/src/vendor/bongos-client.cjs",
|
|
2554
2554
|
"mode": "0000644",
|
|
2555
|
-
"sha256": "
|
|
2555
|
+
"sha256": "43823273ec587b104f3e0296614ae8ea6c4dc5c96261dbbb359ae39c21cf4e79"
|
|
2556
2556
|
},
|
|
2557
2557
|
{
|
|
2558
2558
|
"path": "modules/dev-box/app/test/unit.mjs",
|
|
@@ -3719,6 +3719,11 @@
|
|
|
3719
3719
|
"mode": "0000644",
|
|
3720
3720
|
"sha256": "c25101daed13fc22ba3f132b2dac59c782fa564fa4bc22a6a5169e6644109b3a"
|
|
3721
3721
|
},
|
|
3722
|
+
{
|
|
3723
|
+
"path": "modules/provisioning/migrations/provisioning_005_domain_attach.sql",
|
|
3724
|
+
"mode": "0000644",
|
|
3725
|
+
"sha256": "230e8a9df147495ee5113c1400c582e9e39e3286baab7e01ce7684e1b1c7860c"
|
|
3726
|
+
},
|
|
3722
3727
|
{
|
|
3723
3728
|
"path": "modules/provisioning/module.json",
|
|
3724
3729
|
"mode": "0000644",
|
|
@@ -3732,7 +3737,7 @@
|
|
|
3732
3737
|
{
|
|
3733
3738
|
"path": "modules/provisioning/provisioning.js",
|
|
3734
3739
|
"mode": "0000644",
|
|
3735
|
-
"sha256": "
|
|
3740
|
+
"sha256": "48c047c48579a1cb5cc6b36c2148bcab5c1736a16c4c73c0741a8998bfe922cd"
|
|
3736
3741
|
},
|
|
3737
3742
|
{
|
|
3738
3743
|
"path": "modules/provisioning/rate-limit.js",
|
|
@@ -3742,7 +3747,7 @@
|
|
|
3742
3747
|
{
|
|
3743
3748
|
"path": "modules/provisioning/routes/provisioning.js",
|
|
3744
3749
|
"mode": "0000644",
|
|
3745
|
-
"sha256": "
|
|
3750
|
+
"sha256": "a490a4b4b607a302533bac6fedbc39a0153d57e35a086bcc20079fbefc6815e5"
|
|
3746
3751
|
},
|
|
3747
3752
|
{
|
|
3748
3753
|
"path": "modules/provisioning/tests/provisioning.mjs",
|
|
@@ -4032,12 +4037,12 @@
|
|
|
4032
4037
|
{
|
|
4033
4038
|
"path": "package-lock.json",
|
|
4034
4039
|
"mode": "0000644",
|
|
4035
|
-
"sha256": "
|
|
4040
|
+
"sha256": "9b320dfef27bca09c1ab23bb85c04b499724208dad01a608763f18b9c4e1d1b4"
|
|
4036
4041
|
},
|
|
4037
4042
|
{
|
|
4038
4043
|
"path": "package.json",
|
|
4039
4044
|
"mode": "0000644",
|
|
4040
|
-
"sha256": "
|
|
4045
|
+
"sha256": "d1720c6790a6aa61a091335cf8873dac1e75dfbb1250c7d484395c95fd8825c6"
|
|
4041
4046
|
},
|
|
4042
4047
|
{
|
|
4043
4048
|
"path": "public-docs/index.html",
|
|
@@ -5007,7 +5012,7 @@
|
|
|
5007
5012
|
{
|
|
5008
5013
|
"path": "scripts/gds/provision.js",
|
|
5009
5014
|
"mode": "0000644",
|
|
5010
|
-
"sha256": "
|
|
5015
|
+
"sha256": "e4108117dbe8dd6493ba41ed053fe8648424ca127b1c26505aa6f6702b2dd94c"
|
|
5011
5016
|
},
|
|
5012
5017
|
{
|
|
5013
5018
|
"path": "scripts/gds/publish-manifest.js",
|
|
@@ -5657,7 +5662,7 @@
|
|
|
5657
5662
|
{
|
|
5658
5663
|
"path": "src/module-api.js",
|
|
5659
5664
|
"mode": "0000644",
|
|
5660
|
-
"sha256": "
|
|
5665
|
+
"sha256": "0126fe1e9af95f3daee985c7a9859e19b5937e023d6a54927b6c5dd7055a83ec"
|
|
5661
5666
|
},
|
|
5662
5667
|
{
|
|
5663
5668
|
"path": "src/module-loader/loader.js",
|
|
@@ -7137,7 +7142,12 @@
|
|
|
7137
7142
|
{
|
|
7138
7143
|
"path": "tests/provision.mjs",
|
|
7139
7144
|
"mode": "0000644",
|
|
7140
|
-
"sha256": "
|
|
7145
|
+
"sha256": "bd8e111c2d5614f79086c5f8298cec6ffdcb7ab57b94565457520d85df0c24a8"
|
|
7146
|
+
},
|
|
7147
|
+
{
|
|
7148
|
+
"path": "tests/provisioning_domain_attach.mjs",
|
|
7149
|
+
"mode": "0000644",
|
|
7150
|
+
"sha256": "241e1b208abbd54a625af050d541344186d93806846a1e7f1cbb0f93dfbab802"
|
|
7141
7151
|
},
|
|
7142
7152
|
{
|
|
7143
7153
|
"path": "tests/provisioning_github_app_routes.mjs",
|
|
@@ -7149,6 +7159,11 @@
|
|
|
7149
7159
|
"mode": "0000644",
|
|
7150
7160
|
"sha256": "9a41d64fba3a8cc8ffdbccb0aea363ca6ccb63909cfeefd4bd0b05ebab052403"
|
|
7151
7161
|
},
|
|
7162
|
+
{
|
|
7163
|
+
"path": "tests/provisioning_teardown_intent.mjs",
|
|
7164
|
+
"mode": "0000644",
|
|
7165
|
+
"sha256": "c5ebacf7e29be4e6afecedf5b8593eef750d497e0c502cfa2be92a89b2cff0a1"
|
|
7166
|
+
},
|
|
7152
7167
|
{
|
|
7153
7168
|
"path": "tests/pruned_lockfile_integrity.mjs",
|
|
7154
7169
|
"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
|
+
- 269 operations across 45 resource groups
|
|
9
9
|
|
|
10
10
|
## Install
|
|
11
11
|
|
|
@@ -523,6 +523,8 @@ function createClient(opts = {}) {
|
|
|
523
523
|
postProvisioningInstances: (args) => request("POST", "/provisioning/instances", { hasBody: true }, args),
|
|
524
524
|
// GET /provisioning/instances/{id} — rank: any-builder — GET /provisioning/instances/:id
|
|
525
525
|
getProvisioningInstancesId: (args) => request("GET", "/provisioning/instances/{id}", { hasBody: false }, args),
|
|
526
|
+
// POST /provisioning/instances/{id}/domain — rank: any-builder — POST /provisioning/instances/:id/domain
|
|
527
|
+
postProvisioningInstancesIdDomain: (args) => request("POST", "/provisioning/instances/{id}/domain", { hasBody: true }, args),
|
|
526
528
|
// POST /provisioning/instances/{id}/force-teardown — rank: metic+archon — POST /provisioning/instances/:id/force-teardown
|
|
527
529
|
postProvisioningInstancesIdForceTeardown: (args) => request("POST", "/provisioning/instances/{id}/force-teardown", { hasBody: true }, args),
|
|
528
530
|
// POST /provisioning/instances/{id}/github-app — rank: any-builder — POST /provisioning/instances/:id/github-app
|
|
@@ -522,6 +522,8 @@ function createClient(opts = {}) {
|
|
|
522
522
|
postProvisioningInstances: (args) => request("POST", "/provisioning/instances", { hasBody: true }, args),
|
|
523
523
|
// GET /provisioning/instances/{id} — rank: any-builder — GET /provisioning/instances/:id
|
|
524
524
|
getProvisioningInstancesId: (args) => request("GET", "/provisioning/instances/{id}", { hasBody: false }, args),
|
|
525
|
+
// POST /provisioning/instances/{id}/domain — rank: any-builder — POST /provisioning/instances/:id/domain
|
|
526
|
+
postProvisioningInstancesIdDomain: (args) => request("POST", "/provisioning/instances/{id}/domain", { hasBody: true }, args),
|
|
525
527
|
// POST /provisioning/instances/{id}/force-teardown — rank: metic+archon — POST /provisioning/instances/:id/force-teardown
|
|
526
528
|
postProvisioningInstancesIdForceTeardown: (args) => request("POST", "/provisioning/instances/{id}/force-teardown", { hasBody: true }, args),
|
|
527
529
|
// POST /provisioning/instances/{id}/github-app — rank: any-builder — POST /provisioning/instances/:id/github-app
|
|
@@ -246,10 +246,12 @@ export interface PostOverrideRequestsIdDecideRequest { decision: string; note?:
|
|
|
246
246
|
export interface PostProjectsInviteRequest { client_id: string; github_login: string }
|
|
247
247
|
export interface PostProjectsRequest { origin: string; name: string; tagline?: string; art_url?: string }
|
|
248
248
|
export interface PostProjectsResponse { project: unknown }
|
|
249
|
-
export interface
|
|
249
|
+
export interface PostProvisioningInstancesIdDomainRequest { domain: string }
|
|
250
|
+
export interface PostProvisioningInstancesIdDomainResponse { ok: boolean; changed: boolean; queued: unknown; domain: unknown; message: unknown }
|
|
251
|
+
export interface PostProvisioningInstancesIdForceTeardownResponse { ok: boolean; queued: unknown; action: unknown; status: unknown; superseded: unknown; message: unknown }
|
|
250
252
|
export interface PostProvisioningInstancesIdGithubAppRequest { account?: string }
|
|
251
253
|
export interface PostProvisioningInstancesIdGithubAppResponse { state: unknown; account: unknown; post_url: unknown; personal_url: unknown; org_url: unknown; org_login: unknown; manifest: unknown; redirect_url: unknown; expires_at: unknown }
|
|
252
|
-
export interface PostProvisioningInstancesIdTeardownResponse { ok: boolean; queued: unknown; action: unknown; status: unknown; message: unknown }
|
|
254
|
+
export interface PostProvisioningInstancesIdTeardownResponse { ok: boolean; queued: unknown; action: unknown; status: unknown; superseded: unknown; message: unknown }
|
|
253
255
|
export interface PostProvisioningInstancesRequest { slug: string; target_ref?: string; hosting_shape?: string; domain?: string; tier?: string; onboard_mode?: string }
|
|
254
256
|
export interface PostSearchMarkRequest { chunk_id?: StringifiableId; useful?: unknown }
|
|
255
257
|
export interface PostSearchRequest { expand?: unknown; q?: string; source_kind?: string; limit?: unknown }
|
|
@@ -756,6 +758,8 @@ export interface BongosClient {
|
|
|
756
758
|
postProvisioningInstances(args: RequestArgs & { body: PostProvisioningInstancesRequest }): Promise<ApiResponse>;
|
|
757
759
|
/** GET /provisioning/instances/{id} — rank: any-builder */
|
|
758
760
|
getProvisioningInstancesId(args?: RequestArgs): Promise<GetProvisioningInstancesIdResponse>;
|
|
761
|
+
/** POST /provisioning/instances/{id}/domain — rank: any-builder */
|
|
762
|
+
postProvisioningInstancesIdDomain(args: RequestArgs & { body: PostProvisioningInstancesIdDomainRequest }): Promise<PostProvisioningInstancesIdDomainResponse>;
|
|
759
763
|
/** POST /provisioning/instances/{id}/force-teardown — rank: metic+archon */
|
|
760
764
|
postProvisioningInstancesIdForceTeardown(args?: RequestArgs): Promise<PostProvisioningInstancesIdForceTeardownResponse>;
|
|
761
765
|
/** POST /provisioning/instances/{id}/github-app — rank: any-builder */
|
|
@@ -519,6 +519,8 @@ export function createClient(opts = {}) {
|
|
|
519
519
|
postProvisioningInstances: (args) => request("POST", "/provisioning/instances", { hasBody: true }, args),
|
|
520
520
|
// GET /provisioning/instances/{id} — rank: any-builder — GET /provisioning/instances/:id
|
|
521
521
|
getProvisioningInstancesId: (args) => request("GET", "/provisioning/instances/{id}", { hasBody: false }, args),
|
|
522
|
+
// POST /provisioning/instances/{id}/domain — rank: any-builder — POST /provisioning/instances/:id/domain
|
|
523
|
+
postProvisioningInstancesIdDomain: (args) => request("POST", "/provisioning/instances/{id}/domain", { hasBody: true }, args),
|
|
522
524
|
// POST /provisioning/instances/{id}/force-teardown — rank: metic+archon — POST /provisioning/instances/:id/force-teardown
|
|
523
525
|
postProvisioningInstancesIdForceTeardown: (args) => request("POST", "/provisioning/instances/{id}/force-teardown", { hasBody: true }, args),
|
|
524
526
|
// POST /provisioning/instances/{id}/github-app — rank: any-builder — POST /provisioning/instances/:id/github-app
|
package/docs/api/openapi.json
CHANGED
|
@@ -8493,6 +8493,69 @@
|
|
|
8493
8493
|
]
|
|
8494
8494
|
}
|
|
8495
8495
|
},
|
|
8496
|
+
"/provisioning/instances/{id}/domain": {
|
|
8497
|
+
"post": {
|
|
8498
|
+
"operationId": "post_provisioning_instances_id_domain",
|
|
8499
|
+
"tags": [
|
|
8500
|
+
"provisioning"
|
|
8501
|
+
],
|
|
8502
|
+
"summary": "POST /provisioning/instances/:id/domain",
|
|
8503
|
+
"description": "POST /provisioning/instances/:id/domain — give the caller's OWN instance its address (task 1002692, gap 5: no path existed to add a domain after creation). Validates + records the domain; for an already-ACTIVE instance it also enqueues a 'domain-attach' intent the control-plane runner drains (web tier holds no cloud tokens — ADR 0111 §2). A requested/error instance only records it: the (re)provision run wires the domain itself. Re-pointing an existing address is out of scope — refuse truthfully. Body: { domain (required) }.\n\n**Rank:** `any-builder` — Any authenticated builder (row-level ownership enforced in-handler).",
|
|
8504
|
+
"x-rank": "any-builder",
|
|
8505
|
+
"x-source": "modules/provisioning/routes/provisioning.js",
|
|
8506
|
+
"parameters": [
|
|
8507
|
+
{
|
|
8508
|
+
"name": "id",
|
|
8509
|
+
"in": "path",
|
|
8510
|
+
"required": true,
|
|
8511
|
+
"schema": {
|
|
8512
|
+
"type": "string"
|
|
8513
|
+
},
|
|
8514
|
+
"description": "Path parameter `id`."
|
|
8515
|
+
}
|
|
8516
|
+
],
|
|
8517
|
+
"requestBody": {
|
|
8518
|
+
"required": true,
|
|
8519
|
+
"content": {
|
|
8520
|
+
"application/json": {
|
|
8521
|
+
"schema": {
|
|
8522
|
+
"$ref": "#/components/schemas/PostProvisioningInstancesIdDomainRequest"
|
|
8523
|
+
}
|
|
8524
|
+
}
|
|
8525
|
+
},
|
|
8526
|
+
"x-validated": true
|
|
8527
|
+
},
|
|
8528
|
+
"responses": {
|
|
8529
|
+
"200": {
|
|
8530
|
+
"description": "Success.",
|
|
8531
|
+
"content": {
|
|
8532
|
+
"application/json": {
|
|
8533
|
+
"schema": {
|
|
8534
|
+
"$ref": "#/components/schemas/PostProvisioningInstancesIdDomainResponse"
|
|
8535
|
+
}
|
|
8536
|
+
}
|
|
8537
|
+
}
|
|
8538
|
+
},
|
|
8539
|
+
"400": {
|
|
8540
|
+
"$ref": "#/components/responses/ValidationFailed"
|
|
8541
|
+
},
|
|
8542
|
+
"401": {
|
|
8543
|
+
"$ref": "#/components/responses/Unauthorized"
|
|
8544
|
+
},
|
|
8545
|
+
"403": {
|
|
8546
|
+
"$ref": "#/components/responses/Forbidden"
|
|
8547
|
+
},
|
|
8548
|
+
"404": {
|
|
8549
|
+
"$ref": "#/components/responses/NotFound"
|
|
8550
|
+
}
|
|
8551
|
+
},
|
|
8552
|
+
"security": [
|
|
8553
|
+
{
|
|
8554
|
+
"builderSession": []
|
|
8555
|
+
}
|
|
8556
|
+
]
|
|
8557
|
+
}
|
|
8558
|
+
},
|
|
8496
8559
|
"/provisioning/instances/{id}/force-teardown": {
|
|
8497
8560
|
"post": {
|
|
8498
8561
|
"operationId": "post_provisioning_instances_id_force_teardown",
|
|
@@ -15628,6 +15691,40 @@
|
|
|
15628
15691
|
"project"
|
|
15629
15692
|
]
|
|
15630
15693
|
},
|
|
15694
|
+
"PostProvisioningInstancesIdDomainRequest": {
|
|
15695
|
+
"type": "object",
|
|
15696
|
+
"properties": {
|
|
15697
|
+
"domain": {
|
|
15698
|
+
"type": "string",
|
|
15699
|
+
"maxLength": 253
|
|
15700
|
+
}
|
|
15701
|
+
},
|
|
15702
|
+
"required": [
|
|
15703
|
+
"domain"
|
|
15704
|
+
],
|
|
15705
|
+
"additionalProperties": false
|
|
15706
|
+
},
|
|
15707
|
+
"PostProvisioningInstancesIdDomainResponse": {
|
|
15708
|
+
"type": "object",
|
|
15709
|
+
"properties": {
|
|
15710
|
+
"ok": {
|
|
15711
|
+
"type": "boolean"
|
|
15712
|
+
},
|
|
15713
|
+
"changed": {
|
|
15714
|
+
"type": "boolean"
|
|
15715
|
+
},
|
|
15716
|
+
"queued": {},
|
|
15717
|
+
"domain": {},
|
|
15718
|
+
"message": {}
|
|
15719
|
+
},
|
|
15720
|
+
"required": [
|
|
15721
|
+
"ok",
|
|
15722
|
+
"changed",
|
|
15723
|
+
"queued",
|
|
15724
|
+
"domain",
|
|
15725
|
+
"message"
|
|
15726
|
+
]
|
|
15727
|
+
},
|
|
15631
15728
|
"PostProvisioningInstancesIdForceTeardownResponse": {
|
|
15632
15729
|
"type": "object",
|
|
15633
15730
|
"properties": {
|
|
@@ -15637,6 +15734,7 @@
|
|
|
15637
15734
|
"queued": {},
|
|
15638
15735
|
"action": {},
|
|
15639
15736
|
"status": {},
|
|
15737
|
+
"superseded": {},
|
|
15640
15738
|
"message": {}
|
|
15641
15739
|
},
|
|
15642
15740
|
"required": [
|
|
@@ -15644,6 +15742,7 @@
|
|
|
15644
15742
|
"queued",
|
|
15645
15743
|
"action",
|
|
15646
15744
|
"status",
|
|
15745
|
+
"superseded",
|
|
15647
15746
|
"message"
|
|
15648
15747
|
]
|
|
15649
15748
|
},
|
|
@@ -15691,6 +15790,7 @@
|
|
|
15691
15790
|
"queued": {},
|
|
15692
15791
|
"action": {},
|
|
15693
15792
|
"status": {},
|
|
15793
|
+
"superseded": {},
|
|
15694
15794
|
"message": {}
|
|
15695
15795
|
},
|
|
15696
15796
|
"required": [
|
|
@@ -15698,6 +15798,7 @@
|
|
|
15698
15798
|
"queued",
|
|
15699
15799
|
"action",
|
|
15700
15800
|
"status",
|
|
15801
|
+
"superseded",
|
|
15701
15802
|
"message"
|
|
15702
15803
|
]
|
|
15703
15804
|
},
|
|
@@ -16871,9 +16972,9 @@
|
|
|
16871
16972
|
"description": "A required dependency/feature is not configured or is temporarily down."
|
|
16872
16973
|
}
|
|
16873
16974
|
},
|
|
16874
|
-
"x-endpoint-count":
|
|
16875
|
-
"x-schema-count":
|
|
16975
|
+
"x-endpoint-count": 269,
|
|
16976
|
+
"x-schema-count": 302,
|
|
16876
16977
|
"x-undocumented-bodies": 8,
|
|
16877
|
-
"x-response-schemas":
|
|
16978
|
+
"x-response-schemas": 204,
|
|
16878
16979
|
"x-generated-by": "scripts/gds/gen-api-docs.js"
|
|
16879
16980
|
}
|
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. 269 endpoints across 44 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`.
|
|
@@ -358,7 +358,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
358
358
|
| GET | `/api/bongos/projects/featured` | `public` | — | a curated public showcase; no auth by design. |
|
|
359
359
|
| POST | `/api/bongos/projects/invite` | `metic+archon` | `client_id`, `github_login` | invite a builder into a project (ADR 0141 §5, task #1002115). |
|
|
360
360
|
|
|
361
|
-
## `provisioning` (
|
|
361
|
+
## `provisioning` (14)
|
|
362
362
|
|
|
363
363
|
| Method | Path | Rank | Body | Description |
|
|
364
364
|
|---|---|---|---|---|
|
|
@@ -370,6 +370,7 @@ Base path: `/api/bongos`. Ranks (enforced server-side, [ADR 0016](adr/<redacted>
|
|
|
370
370
|
| GET | `/api/bongos/provisioning/instances` | `any-builder` | — | GET /provisioning/instances — the caller's own instances + each open intent. |
|
|
371
371
|
| POST | `/api/bongos/provisioning/instances` | `any-builder` | `slug`, `target_ref`, `hosting_shape`, `domain`, `tier`, `onboard_mode` | POST /provisioning/instances — request a new instance. |
|
|
372
372
|
| GET | `/api/bongos/provisioning/instances/:id` | `any-builder` | — | GET /provisioning/instances/:id — read one of the caller's own instances. |
|
|
373
|
+
| POST | `/api/bongos/provisioning/instances/:id/domain` | `any-builder` | `domain` | POST /provisioning/instances/:id/domain — give the caller's OWN instance its address (task 1002692, gap 5: no path existed to add a domai… |
|
|
373
374
|
| POST | `/api/bongos/provisioning/instances/:id/force-teardown` | `metic+archon` | — | POST /provisioning/instances/:id/force-teardown — Archon tears down ANY instance. |
|
|
374
375
|
| POST | `/api/bongos/provisioning/instances/:id/github-app` | `any-builder` | `account` | POST /provisioning/instances/:id/github-app — mint a GitHub-App-Manifest onboarding link for the caller's OWN instance (task 2080, ADR 01… |
|
|
375
376
|
| POST | `/api/bongos/provisioning/instances/:id/teardown` | `any-builder` | — | POST /provisioning/instances/:id/teardown — request teardown of the caller's OWN instance. |
|
|
@@ -522,6 +522,8 @@ function createClient(opts = {}) {
|
|
|
522
522
|
postProvisioningInstances: (args) => request("POST", "/provisioning/instances", { hasBody: true }, args),
|
|
523
523
|
// GET /provisioning/instances/{id} — rank: any-builder — GET /provisioning/instances/:id
|
|
524
524
|
getProvisioningInstancesId: (args) => request("GET", "/provisioning/instances/{id}", { hasBody: false }, args),
|
|
525
|
+
// POST /provisioning/instances/{id}/domain — rank: any-builder — POST /provisioning/instances/:id/domain
|
|
526
|
+
postProvisioningInstancesIdDomain: (args) => request("POST", "/provisioning/instances/{id}/domain", { hasBody: true }, args),
|
|
525
527
|
// POST /provisioning/instances/{id}/force-teardown — rank: metic+archon — POST /provisioning/instances/:id/force-teardown
|
|
526
528
|
postProvisioningInstancesIdForceTeardown: (args) => request("POST", "/provisioning/instances/{id}/force-teardown", { hasBody: true }, args),
|
|
527
529
|
// POST /provisioning/instances/{id}/github-app — rank: any-builder — POST /provisioning/instances/:id/github-app
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
-- provisioning_005_domain_attach.sql — the domain-attach intent action
|
|
2
|
+
-- (task 1002692, gap 5 of the creation-flow audit / idea 1000677).
|
|
3
|
+
--
|
|
4
|
+
-- WHY. No path existed to give an EXISTING instance its address: a slug re-request
|
|
5
|
+
-- silently dropped the domain in the body, and a domainless instance stayed
|
|
6
|
+
-- domainless forever — which also blocked GitHub sign-in (the github-app manifest
|
|
7
|
+
-- route requires a domain). The new owner-scoped POST /provisioning/instances/:id/
|
|
8
|
+
-- domain records the domain and, for an already-ACTIVE instance, enqueues a
|
|
9
|
+
-- 'domain-attach' intent; the control-plane runner (the sole token-holder, ADR 0111
|
|
10
|
+
-- §2) re-asserts the domain-dependent standup legs (web.env origins + service
|
|
11
|
+
-- restart, Cloudflare A-record UPSERT, Caddy snippet + reload, healthz). The web
|
|
12
|
+
-- tier still only ENQUEUES — the trust boundary is unchanged.
|
|
13
|
+
--
|
|
14
|
+
-- Widening a CHECK enum is additive (permits MORE values; no row changes) — the
|
|
15
|
+
-- provisioning_003 precedent. Applied only when the provisioning module is enabled.
|
|
16
|
+
-- Safe to re-run. Keep INTENT_ACTIONS in provisioning.js in lockstep.
|
|
17
|
+
|
|
18
|
+
ALTER TABLE provisioning_intents DROP CONSTRAINT IF EXISTS provisioning_intents_action_check;
|
|
19
|
+
ALTER TABLE provisioning_intents ADD CONSTRAINT provisioning_intents_action_check
|
|
20
|
+
CHECK (action IN ('provision', 'teardown', 'oauth-manifest', 'domain-attach'));
|
|
@@ -33,11 +33,25 @@ const ONBOARD_MODES = ['greenfield', 'adopt'];
|
|
|
33
33
|
// conversion. Today the runner drains it by scanning provisioning_oauth_manifests
|
|
34
34
|
// (drainOAuthManifests), not the intent queue, but it stays a valid action so the
|
|
35
35
|
// widened CHECK (migration provisioning_003) and this list never drift.
|
|
36
|
-
|
|
36
|
+
// 'domain-attach' (task 1002692, migration provisioning_005): re-assert the
|
|
37
|
+
// domain-dependent standup legs for an already-ACTIVE instance that was just
|
|
38
|
+
// given its address via POST /provisioning/instances/:id/domain.
|
|
39
|
+
const INTENT_ACTIONS = ['provision', 'teardown', 'oauth-manifest', 'domain-attach'];
|
|
37
40
|
// The states from which a teardown is meaningful (there is something to reclaim).
|
|
38
41
|
// Mirrors dev-box canTransition('deprovision', …): a requested/torn_down/error
|
|
39
42
|
// instance has nothing running to tear down via the happy path.
|
|
40
43
|
const TEARDOWN_FROM = new Set(['provisioning', 'active', 'tearing_down']);
|
|
44
|
+
// The states from which (re)enqueueing a 'provision' intent is meaningful. An
|
|
45
|
+
// 'active' instance needs no standup — blindly re-enqueueing one on a slug
|
|
46
|
+
// re-request left a stale open provision intent that then blocked the owner's
|
|
47
|
+
// teardown on the action-blind ux_provisioning_intents_open (task 1002691);
|
|
48
|
+
// 'tearing_down' is mid-reclaim (any open slot belongs to the teardown).
|
|
49
|
+
const PROVISION_ENQUEUE_FROM = new Set(['requested', 'provisioning', 'error', 'torn_down']);
|
|
50
|
+
// The states from which attaching a domain is meaningful (task 1002692): 'active'
|
|
51
|
+
// needs a 'domain-attach' intent (the runner re-asserts the domain legs);
|
|
52
|
+
// 'requested'/'error' only record it — the (re)provision run wires the domain
|
|
53
|
+
// itself. Mid-flight or torn-down states refuse truthfully.
|
|
54
|
+
const DOMAIN_ATTACH_FROM = new Set(['requested', 'error', 'active']);
|
|
41
55
|
|
|
42
56
|
// Monthly cost estimate (USD) for a dedicated droplet tier — VISIBILITY only
|
|
43
57
|
// (ADR 0111 §6), never a bill. A small local table so this module needs no
|
|
@@ -248,6 +262,29 @@ async function getInstanceBySlug(db, slug) {
|
|
|
248
262
|
return rows[0] || null;
|
|
249
263
|
}
|
|
250
264
|
|
|
265
|
+
// The instance currently holding `domain` (case-insensitive), if any — backs the
|
|
266
|
+
// domain-attach route's uniqueness check so one owner's address can never silently
|
|
267
|
+
// shadow another's (task 1002692). Caller normalizes; matching is defensive anyway.
|
|
268
|
+
async function getInstanceByDomain(db, domain) {
|
|
269
|
+
if (!domain) return null;
|
|
270
|
+
const { rows } = await db.query(
|
|
271
|
+
`SELECT * FROM provisioning_instances WHERE lower(domain) = $1 LIMIT 1`,
|
|
272
|
+
[String(domain).toLowerCase()]
|
|
273
|
+
);
|
|
274
|
+
return rows[0] || null;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Record an instance's domain — the ONLY column this touches (task 1002692). Status
|
|
278
|
+
// changes stay setInstanceStatus's job; keeping this narrow means the domain-attach
|
|
279
|
+
// route can never drift an instance's lifecycle as a side effect.
|
|
280
|
+
async function updateInstanceDomain(db, id, domain) {
|
|
281
|
+
const { rows } = await db.query(
|
|
282
|
+
`UPDATE provisioning_instances SET domain = $2, updated_at = now() WHERE id = $1 RETURNING *`,
|
|
283
|
+
[id, domain]
|
|
284
|
+
);
|
|
285
|
+
return rows[0] || null;
|
|
286
|
+
}
|
|
287
|
+
|
|
251
288
|
// The caller's own instances, newest first.
|
|
252
289
|
async function listInstancesForOwner(db, ownerBuilderId) {
|
|
253
290
|
const { rows } = await db.query(
|
|
@@ -350,6 +387,31 @@ async function enqueueIntent(db, instanceId, action, requestedBy) {
|
|
|
350
387
|
}
|
|
351
388
|
}
|
|
352
389
|
|
|
390
|
+
// Queue a teardown, superseding a stale PENDING provision intent if one holds the
|
|
391
|
+
// open slot (task 1002691: ux_provisioning_intents_open is action-blind, so the old
|
|
392
|
+
// blind enqueue collided with such an intent and the API falsely said "teardown
|
|
393
|
+
// already queued" — the instance leaked). A pending provision is flipped to 'error'
|
|
394
|
+
// (the state CHECK has no 'superseded'; last_error says why) so the runner never
|
|
395
|
+
// stands it up. A RUNNING provision is mid-flight infra work and is never yanked —
|
|
396
|
+
// the caller gets { conflict: 'open_intent' } with the blocking intent so the route
|
|
397
|
+
// can answer truthfully. Each statement is atomic and the index stays the arbiter:
|
|
398
|
+
// any interleaving with the runner or a concurrent enqueue lands on one of these
|
|
399
|
+
// truthful outcomes.
|
|
400
|
+
async function enqueueTeardown(db, instanceId, requestedBy) {
|
|
401
|
+
const { rows: superseded } = await db.query(
|
|
402
|
+
`UPDATE provisioning_intents
|
|
403
|
+
SET state = 'error', last_error = 'superseded: teardown requested',
|
|
404
|
+
updated_at = now(), resolved_at = now()
|
|
405
|
+
WHERE instance_id = $1 AND action = 'provision' AND state = 'pending'
|
|
406
|
+
RETURNING id`,
|
|
407
|
+
[instanceId]
|
|
408
|
+
);
|
|
409
|
+
const { intent, created } = await enqueueIntent(db, instanceId, 'teardown', requestedBy);
|
|
410
|
+
if (created) return { intent, created: true, superseded: superseded.length > 0 };
|
|
411
|
+
if (intent.action === 'teardown') return { intent, created: false, superseded: false };
|
|
412
|
+
return { intent, created: false, superseded: false, conflict: 'open_intent' };
|
|
413
|
+
}
|
|
414
|
+
|
|
353
415
|
// The instance's currently-open (pending|running) intent, if any.
|
|
354
416
|
async function getOpenIntent(db, instanceId) {
|
|
355
417
|
const { rows } = await db.query(
|
|
@@ -540,16 +602,16 @@ async function costLedger(db, { limit = 500 } = {}) {
|
|
|
540
602
|
module.exports = {
|
|
541
603
|
// constants
|
|
542
604
|
INSTANCE_STATES, HOSTING_SHAPES, ONBOARD_MODES, INTENT_ACTIONS, TEARDOWN_FROM,
|
|
543
|
-
TIER_MONTHLY_USD, CERT_ELIGIBLE_STATES,
|
|
605
|
+
PROVISION_ENQUEUE_FROM, DOMAIN_ATTACH_FROM, TIER_MONTHLY_USD, CERT_ELIGIBLE_STATES,
|
|
544
606
|
// pure
|
|
545
607
|
isValidSlug, costEstimateUsd, publicInstance, normalizeHostname,
|
|
546
608
|
// pure — GitHub App Manifest flow (task 2080)
|
|
547
609
|
githubAppName, buildGithubAppManifest, manifestPostUrl,
|
|
548
610
|
// data access
|
|
549
611
|
isProvisionedHostname,
|
|
550
|
-
getInstanceById, getInstanceBySlug, listInstancesForOwner, listAllInstances,
|
|
551
|
-
createInstance, setInstanceStatus,
|
|
552
|
-
enqueueIntent, getOpenIntent, claimNextIntent, resolveIntent,
|
|
612
|
+
getInstanceById, getInstanceBySlug, getInstanceByDomain, listInstancesForOwner, listAllInstances,
|
|
613
|
+
createInstance, setInstanceStatus, updateInstanceDomain,
|
|
614
|
+
enqueueIntent, enqueueTeardown, getOpenIntent, claimNextIntent, resolveIntent,
|
|
553
615
|
recordEvent, instanceStateForSlug, costLedger,
|
|
554
616
|
// data access — GitHub App Manifest attempts (task 2080)
|
|
555
617
|
createOAuthManifest, getOAuthManifestByState, attachManifestCode,
|