@bongos/core 1.19.337 → 1.19.339
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 +31 -31
- package/docs/adr/0055-server-mediated-branch-publish.md +12 -0
- package/docs/adr/0176-private-repo-deploy-keys.md +12 -2
- package/modules/builder-settings/routes/settings.js +18 -16
- package/modules/dev-box/routes/box.js +25 -23
- package/modules/discord/discord-bot.js +37 -35
- package/modules/discord/discord-role-sync.js +14 -12
- package/modules/government/routes/government.js +15 -13
- package/modules/ideas/routes/inbox.js +16 -14
- package/modules/lifecycle/routes/claims.js +11 -9
- package/modules/lifecycle/routes/goals.js +25 -23
- package/modules/lifecycle/routes/task-write-routes.js +17 -15
- package/modules/lifecycle/routes/tasks.js +21 -19
- package/modules/memory/routes/memory.js +18 -16
- package/modules/platform-identity/routes/sso.js +13 -11
- package/modules/provisioning/routes/provisioning.js +17 -15
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/fitness.js +6 -0
- package/src/bongos/auth-admission.js +9 -6
- package/src/bongos/routes/auth.js +20 -17
- package/src/bongos/routes/backup.js +7 -4
- package/src/bongos/routes/builders.js +17 -14
- package/src/bongos/routes/public.js +9 -6
- package/src/bongos/uptime-poller.js +8 -5
- package/src/module-api.js +44 -6
- package/tests/logger.mjs +67 -0
package/.bongos-core.json
CHANGED
|
@@ -2,11 +2,11 @@
|
|
|
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.339",
|
|
6
|
+
"core_contract": "1.19.339",
|
|
7
|
+
"source_commit": "2fec46ecdc4aff13a2b42b6dd37e7151fa7a7c6c",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-08-25T01:
|
|
9
|
+
"built_at": "2026-08-25T01:23:32.854Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 325,
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
19
|
"file_count": 1830,
|
|
20
|
-
"tree_sha256": "
|
|
20
|
+
"tree_sha256": "7a407b4e4d5c929c91502bf31d949fb6bbf8634ce0a2ea6caa9b7dd48ddfbdd9",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/blocker-review/SKILL.md",
|
|
@@ -707,7 +707,7 @@
|
|
|
707
707
|
{
|
|
708
708
|
"path": "docs/adr/0055-server-mediated-branch-publish.md",
|
|
709
709
|
"mode": "0000644",
|
|
710
|
-
"sha256": "
|
|
710
|
+
"sha256": "5607ab08040d7127fbdad579cf091166b5be5eb6e39a88d3e7337e4f94171fee"
|
|
711
711
|
},
|
|
712
712
|
{
|
|
713
713
|
"path": "docs/adr/0056-prod-deploy-script-mirror-and-healthcheck-retry.md",
|
|
@@ -1362,7 +1362,7 @@
|
|
|
1362
1362
|
{
|
|
1363
1363
|
"path": "docs/adr/0176-private-repo-deploy-keys.md",
|
|
1364
1364
|
"mode": "0000644",
|
|
1365
|
-
"sha256": "
|
|
1365
|
+
"sha256": "80c1b9d283892454f45504fe3f20f3a215967de7cca66a5b3ef30970bb8eed47"
|
|
1366
1366
|
},
|
|
1367
1367
|
{
|
|
1368
1368
|
"path": "docs/adr/0177-goal-membership-kind.md",
|
|
@@ -2542,7 +2542,7 @@
|
|
|
2542
2542
|
{
|
|
2543
2543
|
"path": "modules/builder-settings/routes/settings.js",
|
|
2544
2544
|
"mode": "0000644",
|
|
2545
|
-
"sha256": "
|
|
2545
|
+
"sha256": "c5198a5fb915be1015eec09ca0b614c96d820fdf491cb56d1c735b8839a441c0"
|
|
2546
2546
|
},
|
|
2547
2547
|
{
|
|
2548
2548
|
"path": "modules/builder-settings/settings.js",
|
|
@@ -2872,7 +2872,7 @@
|
|
|
2872
2872
|
{
|
|
2873
2873
|
"path": "modules/dev-box/routes/box.js",
|
|
2874
2874
|
"mode": "0000644",
|
|
2875
|
-
"sha256": "
|
|
2875
|
+
"sha256": "4310c28d74085f2544f92e2191e7cbc4d646bbc4e304fec83099298e5f8d9c93"
|
|
2876
2876
|
},
|
|
2877
2877
|
{
|
|
2878
2878
|
"path": "modules/discord/CLAUDE.md",
|
|
@@ -2912,7 +2912,7 @@
|
|
|
2912
2912
|
{
|
|
2913
2913
|
"path": "modules/discord/discord-bot.js",
|
|
2914
2914
|
"mode": "0000644",
|
|
2915
|
-
"sha256": "
|
|
2915
|
+
"sha256": "7bdd8892cf1dcc7edddcc2e8f95d3174b7f902be83fd0a34ecfc2b7cc998ce55"
|
|
2916
2916
|
},
|
|
2917
2917
|
{
|
|
2918
2918
|
"path": "modules/discord/discord-bugs.js",
|
|
@@ -2942,7 +2942,7 @@
|
|
|
2942
2942
|
{
|
|
2943
2943
|
"path": "modules/discord/discord-role-sync.js",
|
|
2944
2944
|
"mode": "0000644",
|
|
2945
|
-
"sha256": "
|
|
2945
|
+
"sha256": "852abc58bdec011b6d3bf222a35e198c6ea98a761d57a76be85477ef85ae54f5"
|
|
2946
2946
|
},
|
|
2947
2947
|
{
|
|
2948
2948
|
"path": "modules/discord/migrations/discord_001_board_messages.sql",
|
|
@@ -3192,7 +3192,7 @@
|
|
|
3192
3192
|
{
|
|
3193
3193
|
"path": "modules/government/routes/government.js",
|
|
3194
3194
|
"mode": "0000644",
|
|
3195
|
-
"sha256": "
|
|
3195
|
+
"sha256": "8b29ea6478f4854dd5c74ea3538079db818707a575318634ce4f7504d2768289"
|
|
3196
3196
|
},
|
|
3197
3197
|
{
|
|
3198
3198
|
"path": "modules/government/routes/rank-sync.js",
|
|
@@ -3842,7 +3842,7 @@
|
|
|
3842
3842
|
{
|
|
3843
3843
|
"path": "modules/ideas/routes/inbox.js",
|
|
3844
3844
|
"mode": "0000644",
|
|
3845
|
-
"sha256": "
|
|
3845
|
+
"sha256": "0215d0eadab112c023af4e67a1fa81060b0844334d29e3943f8c388f64cda533"
|
|
3846
3846
|
},
|
|
3847
3847
|
{
|
|
3848
3848
|
"path": "modules/ideas/routing.js",
|
|
@@ -4047,7 +4047,7 @@
|
|
|
4047
4047
|
{
|
|
4048
4048
|
"path": "modules/lifecycle/routes/claims.js",
|
|
4049
4049
|
"mode": "0000644",
|
|
4050
|
-
"sha256": "
|
|
4050
|
+
"sha256": "fb5dda00e0c378e2fb8b3190fdeaf4562be65097895bd67b68e67428a14c8297"
|
|
4051
4051
|
},
|
|
4052
4052
|
{
|
|
4053
4053
|
"path": "modules/lifecycle/routes/dependencies.js",
|
|
@@ -4072,7 +4072,7 @@
|
|
|
4072
4072
|
{
|
|
4073
4073
|
"path": "modules/lifecycle/routes/goals.js",
|
|
4074
4074
|
"mode": "0000644",
|
|
4075
|
-
"sha256": "
|
|
4075
|
+
"sha256": "bfc87f9887cfe03abfdec0a9a3139917099922fc37d56fb0fcb4ec47980fb53b"
|
|
4076
4076
|
},
|
|
4077
4077
|
{
|
|
4078
4078
|
"path": "modules/lifecycle/routes/help-requests.js",
|
|
@@ -4092,12 +4092,12 @@
|
|
|
4092
4092
|
{
|
|
4093
4093
|
"path": "modules/lifecycle/routes/task-write-routes.js",
|
|
4094
4094
|
"mode": "0000644",
|
|
4095
|
-
"sha256": "
|
|
4095
|
+
"sha256": "d4b1eb471d334fdf164acd76814cc19358030b8d02146f51481d61a990925e41"
|
|
4096
4096
|
},
|
|
4097
4097
|
{
|
|
4098
4098
|
"path": "modules/lifecycle/routes/tasks.js",
|
|
4099
4099
|
"mode": "0000644",
|
|
4100
|
-
"sha256": "
|
|
4100
|
+
"sha256": "07a56f93428baf4d8cbf7a69a76c052e706ec7759134fcf3db153a37c9ab575c"
|
|
4101
4101
|
},
|
|
4102
4102
|
{
|
|
4103
4103
|
"path": "modules/lifecycle/routes/versions.js",
|
|
@@ -4157,7 +4157,7 @@
|
|
|
4157
4157
|
{
|
|
4158
4158
|
"path": "modules/memory/routes/memory.js",
|
|
4159
4159
|
"mode": "0000644",
|
|
4160
|
-
"sha256": "
|
|
4160
|
+
"sha256": "f3b2f6f003acb77e004259ef62ae2b4cd81dddf3d761550086c687b63f6b8ff7"
|
|
4161
4161
|
},
|
|
4162
4162
|
{
|
|
4163
4163
|
"path": "modules/memory/routes/search.js",
|
|
@@ -4337,7 +4337,7 @@
|
|
|
4337
4337
|
{
|
|
4338
4338
|
"path": "modules/platform-identity/routes/sso.js",
|
|
4339
4339
|
"mode": "0000644",
|
|
4340
|
-
"sha256": "
|
|
4340
|
+
"sha256": "9b86c847d2b014fb9929fb655097496d6226c0cd1507c6fdf5ffdd2da6f84eb9"
|
|
4341
4341
|
},
|
|
4342
4342
|
{
|
|
4343
4343
|
"path": "modules/platform-identity/tests/platform-identity.mjs",
|
|
@@ -4427,7 +4427,7 @@
|
|
|
4427
4427
|
{
|
|
4428
4428
|
"path": "modules/provisioning/routes/provisioning.js",
|
|
4429
4429
|
"mode": "0000644",
|
|
4430
|
-
"sha256": "
|
|
4430
|
+
"sha256": "5e9b3d225f06ab2d92b1f85d0d338ae6fa9aaae31afad92b043172e048455895"
|
|
4431
4431
|
},
|
|
4432
4432
|
{
|
|
4433
4433
|
"path": "modules/provisioning/tests/liveness.mjs",
|
|
@@ -4727,12 +4727,12 @@
|
|
|
4727
4727
|
{
|
|
4728
4728
|
"path": "package-lock.json",
|
|
4729
4729
|
"mode": "0000644",
|
|
4730
|
-
"sha256": "
|
|
4730
|
+
"sha256": "d422f518f25f5a4063fa0f114cb86ee4b501e8362e8c0f0f526707d8d6ec137d"
|
|
4731
4731
|
},
|
|
4732
4732
|
{
|
|
4733
4733
|
"path": "package.json",
|
|
4734
4734
|
"mode": "0000644",
|
|
4735
|
-
"sha256": "
|
|
4735
|
+
"sha256": "4988c346e6258b2eca07502ffdf4991652f381983258a2a13de47dc4cafc72b6"
|
|
4736
4736
|
},
|
|
4737
4737
|
{
|
|
4738
4738
|
"path": "public-docs/index.html",
|
|
@@ -5407,7 +5407,7 @@
|
|
|
5407
5407
|
{
|
|
5408
5408
|
"path": "scripts/gds/fitness.js",
|
|
5409
5409
|
"mode": "0000644",
|
|
5410
|
-
"sha256": "
|
|
5410
|
+
"sha256": "0181ba9d5595199777a84b1bc8363d5cda55df68c1eeecb647a18c4fbb6697df"
|
|
5411
5411
|
},
|
|
5412
5412
|
{
|
|
5413
5413
|
"path": "scripts/gds/gate-review.js",
|
|
@@ -6287,7 +6287,7 @@
|
|
|
6287
6287
|
{
|
|
6288
6288
|
"path": "src/bongos/auth-admission.js",
|
|
6289
6289
|
"mode": "0000644",
|
|
6290
|
-
"sha256": "
|
|
6290
|
+
"sha256": "74830f017c5472e2420095e158c905dccfd046d1442263b374ae87f2ceebde86"
|
|
6291
6291
|
},
|
|
6292
6292
|
{
|
|
6293
6293
|
"path": "src/bongos/auth-config.js",
|
|
@@ -6447,17 +6447,17 @@
|
|
|
6447
6447
|
{
|
|
6448
6448
|
"path": "src/bongos/routes/auth.js",
|
|
6449
6449
|
"mode": "0000644",
|
|
6450
|
-
"sha256": "
|
|
6450
|
+
"sha256": "be7b68b01d82fb3ac714d92f22b6adbc1788fb47b9ce8345d4cf14bd1fb92e94"
|
|
6451
6451
|
},
|
|
6452
6452
|
{
|
|
6453
6453
|
"path": "src/bongos/routes/backup.js",
|
|
6454
6454
|
"mode": "0000644",
|
|
6455
|
-
"sha256": "
|
|
6455
|
+
"sha256": "b6bab9ff17e967cbdb18d29f7e027d0ab74874c8b444434f955456829a5ed547"
|
|
6456
6456
|
},
|
|
6457
6457
|
{
|
|
6458
6458
|
"path": "src/bongos/routes/builders.js",
|
|
6459
6459
|
"mode": "0000644",
|
|
6460
|
-
"sha256": "
|
|
6460
|
+
"sha256": "afc0f563da646c6a2d7c3b1adeaeaaf19cf2db48251005f6f003511d2dba65e9"
|
|
6461
6461
|
},
|
|
6462
6462
|
{
|
|
6463
6463
|
"path": "src/bongos/routes/github.js",
|
|
@@ -6502,7 +6502,7 @@
|
|
|
6502
6502
|
{
|
|
6503
6503
|
"path": "src/bongos/routes/public.js",
|
|
6504
6504
|
"mode": "0000644",
|
|
6505
|
-
"sha256": "
|
|
6505
|
+
"sha256": "a6cf425b755630a6720ed4099ecb187131d8c0dbb9d2d6a02d0a4f5915e2ecb5"
|
|
6506
6506
|
},
|
|
6507
6507
|
{
|
|
6508
6508
|
"path": "src/bongos/routes/security.js",
|
|
@@ -6532,7 +6532,7 @@
|
|
|
6532
6532
|
{
|
|
6533
6533
|
"path": "src/bongos/uptime-poller.js",
|
|
6534
6534
|
"mode": "0000644",
|
|
6535
|
-
"sha256": "
|
|
6535
|
+
"sha256": "2237a2938586f9600974e01dccec88893bf86cc9cd56c498522f1a9318dffafe"
|
|
6536
6536
|
},
|
|
6537
6537
|
{
|
|
6538
6538
|
"path": "src/branding.js",
|
|
@@ -6557,7 +6557,7 @@
|
|
|
6557
6557
|
{
|
|
6558
6558
|
"path": "src/module-api.js",
|
|
6559
6559
|
"mode": "0000644",
|
|
6560
|
-
"sha256": "
|
|
6560
|
+
"sha256": "930f33a07876e76cf85203ff41de06eb1eebe120508946991f2ad0c73bd0a99c"
|
|
6561
6561
|
},
|
|
6562
6562
|
{
|
|
6563
6563
|
"path": "src/module-loader/catalog.js",
|
|
@@ -8092,7 +8092,7 @@
|
|
|
8092
8092
|
{
|
|
8093
8093
|
"path": "tests/logger.mjs",
|
|
8094
8094
|
"mode": "0000644",
|
|
8095
|
-
"sha256": "
|
|
8095
|
+
"sha256": "edf87a88bd7130e85844db291d5f1d7b6de561434501bdb064dfadf0e23befe1"
|
|
8096
8096
|
},
|
|
8097
8097
|
{
|
|
8098
8098
|
"path": "tests/main_audit.mjs",
|
|
@@ -49,5 +49,17 @@ A **fine-grained GitHub PAT** scoped to the single repo: `Contents: read/write`
|
|
|
49
49
|
- A dev-box builder ships end-to-end: `/builder-reauth` → claim → edit → `/builder-stage` ([ADR 0046](<redacted>.md)) → `/builder-ship`, with the GDS doing the push. The box holds no GitHub credential, so the [ADR 0053](0053-scoped-dev-box-session.md) blast-radius argument still holds.
|
|
50
50
|
- The blast radius moves from "box holds a push credential" to "server holds a branch-push-only PAT." This is the direction blocker [#15](https://example.com/builders#/blocker/15) ([SEC #863](https://example.com/builders#/task/863)) already wants — a server identity holding the push credential, not builder machines.
|
|
51
51
|
- **Follow-up (hardening) — DONE + LIVE (task 1028 code, task 1043 cutover):** the standing PAT is replaced by a **GitHub App** (the server holds only the App private key and mints short-lived, repo-scoped installation tokens per push). See the *Update* above — the App is live on prod and the PAT has been removed.
|
|
52
|
+
- **Verified end-to-end on hardware, 2026-08-25 (task 1003247)** — first proof since the
|
|
53
|
+
repo went private (~2026-08-15). The verification was performed by shipping from a live dev
|
|
54
|
+
box: `/builder-reauth` -> claim -> edit -> `/builder-ship`. The instance that carried it
|
|
55
|
+
through was **task 1003252**, whose ship published its branch and produced **PR #353**,
|
|
56
|
+
which auto-merged and deployed. Task 1003247 is the decision record of that verification --
|
|
57
|
+
it is not the branch PR #353 was opened from. The box demonstrably held no push credential
|
|
58
|
+
at the time: with a working READ credential in hand, `git push --dry-run` returned 403
|
|
59
|
+
`Write access to repository not granted`. A PR nonetheless existing is the proof that the
|
|
60
|
+
server, not the box, did the push. Also exercised: box source-fetch against a PRIVATE repo,
|
|
61
|
+
a non-box-scoped session, bundle upload to `POST /tasks/:id/publish-branch`, and the
|
|
62
|
+
confirmed->shipped flip.
|
|
63
|
+
|
|
52
64
|
- **Residual:** the server verifies the bundle tip == the claimed sha and that the caller holds the claim, but does not cheaply prove every commit in the bundle was authored under the claim — branch protection + required checks on `main` (which the credential cannot bypass) are the real gate, exactly as for any PR.
|
|
53
65
|
- **Operator action — DONE (blocker 31, resolved 2026-06-13):** the GitHub App was created and `GITHUB_APP_ID` + `GITHUB_APP_INSTALLATION_ID` + `GITHUB_APP_PRIVATE_KEY` set on the droplet (task 1043); `GITHUB_PUSH_TOKEN` then removed. To rotate the key: generate a new private key in the App's settings, replace `GITHUB_APP_PRIVATE_KEY` (single-line, literal `\n`) in `/etc/example/web-source.env`, restart `example`. To roll back to the PAT: restore `web-source.env.bak-task1043` and set a fresh `GITHUB_PUSH_TOKEN` (with the App vars absent, `resolveToken()` falls back to the PAT).
|
|
@@ -51,8 +51,18 @@ best-effort revokes the key by title. Pushes keep preferring the owner-token HTT
|
|
|
51
51
|
- The flip-to-private refusal on the manage page (task 1003045) stays until existing
|
|
52
52
|
already-provisioned instances get the same wiring on flip — a follow-up task, since their
|
|
53
53
|
origin still rides the shared alias.
|
|
54
|
-
- Builder **dev boxes** of a private-repo project
|
|
55
|
-
|
|
54
|
+
- Builder **dev boxes** of a private-repo project were parked here as out of scope.
|
|
55
|
+
**Answered on hardware 2026-08-25 (task 1003247): a box CAN read the private repo, and the
|
|
56
|
+
auth design needed no change.** The GDS-backed credential helper (`otb-git-credential`,
|
|
57
|
+
task 1002907) fetches a per-request, per-LIVE-rank credential from `/box/source-access`, so
|
|
58
|
+
`git ls-remote origin` succeeds against the private repo. ADR 0055's posture holds
|
|
59
|
+
underneath it: that same credential is read-only, so `git push` still returns 403 `Write
|
|
60
|
+
access to repository not granted`. The real gap was not box-side auth at all but a
|
|
61
|
+
config-dir mismatch -- `box-source-fetch.sh` and the helper read the legacy
|
|
62
|
+
`~/.config/otb/` while `/builder-reauth` writes to the branding `configDir`, so after a
|
|
63
|
+
re-auth both presented a dead token and every git op died with the opaque "could not read
|
|
64
|
+
Username". Task 1003252 fixed the four tracked `infra/box-*.sh` scripts; the two
|
|
65
|
+
instance-owned consumers are task 1003253.
|
|
56
66
|
- `bongos upgrade --commit-pin` on a private instance pushes its pin via `origin` — now the
|
|
57
67
|
read-only key, so GitHub refuses it and the pull-deploy reset can revert the bump.
|
|
58
68
|
`upgrade.js` needs the owner-token push path (follow-up).
|
|
@@ -29,6 +29,8 @@ const interactionPrefs = require('../interaction-prefs');
|
|
|
29
29
|
const modelAllocPrefs = require('../model-alloc-prefs');
|
|
30
30
|
const renderPrefs = require('../render-prefs');
|
|
31
31
|
const displayName = require('../display-name');
|
|
32
|
+
// task 1003208: structured logging (pino via the doorway) — was console.*.
|
|
33
|
+
const log = api.logger('builder-settings');
|
|
32
34
|
|
|
33
35
|
// Register the `builder-settings` kernel PORT (BV1.R80 / ADR 0093 §1). The core
|
|
34
36
|
// consumers (routes/me.js's GET /me aggregator + cascade-dispatch.js) resolve it
|
|
@@ -67,7 +69,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
67
69
|
allowed_models: skillPrefs.ALLOWED_MODELS,
|
|
68
70
|
});
|
|
69
71
|
} catch (err) {
|
|
70
|
-
|
|
72
|
+
log.error('[gds] GET /me/skill-prefs', err);
|
|
71
73
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
72
74
|
}
|
|
73
75
|
});
|
|
@@ -98,7 +100,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
98
100
|
allowed_models: skillPrefs.ALLOWED_MODELS,
|
|
99
101
|
});
|
|
100
102
|
} catch (err) {
|
|
101
|
-
|
|
103
|
+
log.error('[gds] PATCH /me/skill-prefs', err);
|
|
102
104
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
103
105
|
}
|
|
104
106
|
});
|
|
@@ -124,7 +126,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
124
126
|
known_sounds: soundPrefs.KNOWN_SOUNDS,
|
|
125
127
|
});
|
|
126
128
|
} catch (err) {
|
|
127
|
-
|
|
129
|
+
log.error('[gds] GET /me/sound-prefs', err);
|
|
128
130
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
129
131
|
}
|
|
130
132
|
});
|
|
@@ -156,7 +158,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
156
158
|
known_sounds: soundPrefs.KNOWN_SOUNDS,
|
|
157
159
|
});
|
|
158
160
|
} catch (err) {
|
|
159
|
-
|
|
161
|
+
log.error('[gds] PATCH /me/sound-prefs', err);
|
|
160
162
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
161
163
|
}
|
|
162
164
|
});
|
|
@@ -178,7 +180,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
178
180
|
events: eventSoundPrefs.EVENTS,
|
|
179
181
|
});
|
|
180
182
|
} catch (err) {
|
|
181
|
-
|
|
183
|
+
log.error('[gds] GET /me/event-sound-prefs', err);
|
|
182
184
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
183
185
|
}
|
|
184
186
|
});
|
|
@@ -205,7 +207,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
205
207
|
events: eventSoundPrefs.EVENTS,
|
|
206
208
|
});
|
|
207
209
|
} catch (err) {
|
|
208
|
-
|
|
210
|
+
log.error('[gds] PATCH /me/event-sound-prefs', err);
|
|
209
211
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
210
212
|
}
|
|
211
213
|
});
|
|
@@ -225,7 +227,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
225
227
|
const stored = await db.getBuilderBehaviorPrefs(req.builder.id);
|
|
226
228
|
res.json(wanderingPrefs.describeForApi(stored, builder?.rank));
|
|
227
229
|
} catch (err) {
|
|
228
|
-
|
|
230
|
+
log.error('[gds] GET /me/wandering', err);
|
|
229
231
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
230
232
|
}
|
|
231
233
|
});
|
|
@@ -251,7 +253,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
251
253
|
const saved = await db.setBuilderBehaviorPrefs(req.builder.id, next);
|
|
252
254
|
res.json(wanderingPrefs.describeForApi(saved, builder?.rank));
|
|
253
255
|
} catch (err) {
|
|
254
|
-
|
|
256
|
+
log.error('[gds] PATCH /me/wandering', err);
|
|
255
257
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
256
258
|
}
|
|
257
259
|
});
|
|
@@ -269,7 +271,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
269
271
|
const stored = await db.getBuilderBehaviorPrefs(req.builder.id);
|
|
270
272
|
res.json(interactionPrefs.describeForApi(stored));
|
|
271
273
|
} catch (err) {
|
|
272
|
-
|
|
274
|
+
log.error('[gds] GET /me/interaction', err);
|
|
273
275
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
274
276
|
}
|
|
275
277
|
});
|
|
@@ -289,7 +291,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
289
291
|
const saved = await db.setBuilderBehaviorPrefs(req.builder.id, nextPrefs);
|
|
290
292
|
res.json(interactionPrefs.describeForApi(saved));
|
|
291
293
|
} catch (err) {
|
|
292
|
-
|
|
294
|
+
log.error('[gds] PATCH /me/interaction', err);
|
|
293
295
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
294
296
|
}
|
|
295
297
|
});
|
|
@@ -309,7 +311,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
309
311
|
const stored = await db.getBuilderBehaviorPrefs(req.builder.id);
|
|
310
312
|
res.json(modelAllocPrefs.describeForApi(stored, instanceModels()));
|
|
311
313
|
} catch (err) {
|
|
312
|
-
|
|
314
|
+
log.error('[gds] GET /me/model-allocation', err);
|
|
313
315
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
314
316
|
}
|
|
315
317
|
});
|
|
@@ -329,7 +331,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
329
331
|
const saved = await db.setBuilderBehaviorPrefs(req.builder.id, nextPrefs);
|
|
330
332
|
res.json(modelAllocPrefs.describeForApi(saved, instanceModels()));
|
|
331
333
|
} catch (err) {
|
|
332
|
-
|
|
334
|
+
log.error('[gds] PATCH /me/model-allocation', err);
|
|
333
335
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
334
336
|
}
|
|
335
337
|
});
|
|
@@ -349,7 +351,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
349
351
|
const stored = await db.getBuilderBehaviorPrefs(req.builder.id);
|
|
350
352
|
res.json(renderPrefs.describeForApi(stored));
|
|
351
353
|
} catch (err) {
|
|
352
|
-
|
|
354
|
+
log.error('[gds] GET /me/render', err);
|
|
353
355
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
354
356
|
}
|
|
355
357
|
});
|
|
@@ -371,7 +373,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
371
373
|
const saved = await db.setBuilderBehaviorPrefs(req.builder.id, next);
|
|
372
374
|
res.json(renderPrefs.describeForApi(saved));
|
|
373
375
|
} catch (err) {
|
|
374
|
-
|
|
376
|
+
log.error('[gds] PATCH /me/render', err);
|
|
375
377
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
376
378
|
}
|
|
377
379
|
});
|
|
@@ -388,7 +390,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
388
390
|
const current = await db.getBuilderDisplayName(req.builder.id);
|
|
389
391
|
res.json({ display_name: current, max_length: displayName.MAX_LENGTH });
|
|
390
392
|
} catch (err) {
|
|
391
|
-
|
|
393
|
+
log.error('[gds] GET /me/display-name', err);
|
|
392
394
|
res.fail('read_failed', { status: 500, message: 'internal error' });
|
|
393
395
|
}
|
|
394
396
|
});
|
|
@@ -408,7 +410,7 @@ module.exports = function buildBuilderSettingsRouter() {
|
|
|
408
410
|
const saved = await db.setBuilderDisplayName(req.builder.id, v.value);
|
|
409
411
|
res.json({ display_name: saved, max_length: displayName.MAX_LENGTH });
|
|
410
412
|
} catch (err) {
|
|
411
|
-
|
|
413
|
+
log.error('[gds] PATCH /me/display-name', err);
|
|
412
414
|
res.fail('write_failed', { status: 500, message: 'internal error' });
|
|
413
415
|
}
|
|
414
416
|
});
|
|
@@ -39,6 +39,8 @@ const boxOnboard = require('../box-onboard');
|
|
|
39
39
|
// queries lifted out of core db.js. Kernel reads (getBuilderById) still come
|
|
40
40
|
// from the doorway via `gdsDb`.
|
|
41
41
|
const db = require('../db');
|
|
42
|
+
// task 1003208: structured logging (pino via the doorway) — was console.*.
|
|
43
|
+
const log = api.logger('dev-box');
|
|
42
44
|
|
|
43
45
|
// Repo root, for serving the (non-secret) bootstrap scripts that live in infra/.
|
|
44
46
|
const REPO_ROOT = path.resolve(__dirname, '..', '..', '..');
|
|
@@ -240,7 +242,7 @@ module.exports = function buildBoxRouter() {
|
|
|
240
242
|
})),
|
|
241
243
|
});
|
|
242
244
|
} catch (err) {
|
|
243
|
-
|
|
245
|
+
log.error('[gds] GET /boxes', err);
|
|
244
246
|
res.fail('roster_failed', { status: 500, message: 'internal error' });
|
|
245
247
|
}
|
|
246
248
|
});
|
|
@@ -256,7 +258,7 @@ module.exports = function buildBoxRouter() {
|
|
|
256
258
|
const out = await boxes.boxCostLedger(pool, { limit });
|
|
257
259
|
res.json(out);
|
|
258
260
|
} catch (err) {
|
|
259
|
-
|
|
261
|
+
log.error('[gds] GET /boxes/cost-ledger', err);
|
|
260
262
|
res.fail('cost_ledger_failed', { status: 500, message: 'internal error' });
|
|
261
263
|
}
|
|
262
264
|
});
|
|
@@ -301,7 +303,7 @@ module.exports = function buildBoxRouter() {
|
|
|
301
303
|
: 'A close request is already queued for that box.',
|
|
302
304
|
});
|
|
303
305
|
} catch (err) {
|
|
304
|
-
|
|
306
|
+
log.error('[gds] POST /boxes/:builderId/close', err);
|
|
305
307
|
res.fail('close_failed', { status: 500, message: 'internal error' });
|
|
306
308
|
}
|
|
307
309
|
});
|
|
@@ -379,7 +381,7 @@ module.exports = function buildBoxRouter() {
|
|
|
379
381
|
close_queued: closeQueued,
|
|
380
382
|
});
|
|
381
383
|
} catch (err) {
|
|
382
|
-
|
|
384
|
+
log.error('[gds] PATCH /boxes/:builderId/block', err);
|
|
383
385
|
res.fail('block_failed', { status: 500, message: 'internal error' });
|
|
384
386
|
}
|
|
385
387
|
});
|
|
@@ -403,7 +405,7 @@ module.exports = function buildBoxRouter() {
|
|
|
403
405
|
cost,
|
|
404
406
|
});
|
|
405
407
|
} catch (err) {
|
|
406
|
-
|
|
408
|
+
log.error('[gds] GET /box/me', err);
|
|
407
409
|
res.fail('box_read_failed', { status: 500, message: 'internal error' });
|
|
408
410
|
}
|
|
409
411
|
});
|
|
@@ -449,7 +451,7 @@ module.exports = function buildBoxRouter() {
|
|
|
449
451
|
try {
|
|
450
452
|
scopeKeys = await lifecycle.moduleScopeForActiveClaims(req.builder.id);
|
|
451
453
|
} catch (scopeErr) {
|
|
452
|
-
|
|
454
|
+
log.error('[gds] source-access scope read (non-fatal, → rank scope)', scopeErr && scopeErr.message ? scopeErr.message : scopeErr);
|
|
453
455
|
scopeKeys = undefined;
|
|
454
456
|
}
|
|
455
457
|
}
|
|
@@ -461,7 +463,7 @@ module.exports = function buildBoxRouter() {
|
|
|
461
463
|
try {
|
|
462
464
|
hasActiveClaims = (await lifecycle.activeClaimCountForBuilder(req.builder.id)) > 0;
|
|
463
465
|
} catch (claimErr) {
|
|
464
|
-
|
|
466
|
+
log.error('[gds] source-access claim-count read (non-fatal, → BASE)', claimErr && claimErr.message ? claimErr.message : claimErr);
|
|
465
467
|
hasActiveClaims = undefined;
|
|
466
468
|
}
|
|
467
469
|
}
|
|
@@ -530,7 +532,7 @@ module.exports = function buildBoxRouter() {
|
|
|
530
532
|
} catch (err) {
|
|
531
533
|
// Log the detail server-side; do NOT leak it to the caller — this is a
|
|
532
534
|
// credential-issuing endpoint, and err.message can carry DB/query internals.
|
|
533
|
-
|
|
535
|
+
log.error('[gds] GET /box/source-access', err);
|
|
534
536
|
res.fail('source_access_failed', 500);
|
|
535
537
|
}
|
|
536
538
|
});
|
|
@@ -566,7 +568,7 @@ module.exports = function buildBoxRouter() {
|
|
|
566
568
|
try {
|
|
567
569
|
scopeKeys = await lifecycle.moduleScopeForActiveClaims(req.builder.id);
|
|
568
570
|
} catch (scopeErr) {
|
|
569
|
-
|
|
571
|
+
log.error('[gds] /box/scope scope read (non-fatal, → rank scope)', scopeErr && scopeErr.message ? scopeErr.message : scopeErr);
|
|
570
572
|
scopeKeys = undefined;
|
|
571
573
|
}
|
|
572
574
|
}
|
|
@@ -577,7 +579,7 @@ module.exports = function buildBoxRouter() {
|
|
|
577
579
|
try {
|
|
578
580
|
hasActiveClaims = (await lifecycle.activeClaimCountForBuilder(req.builder.id)) > 0;
|
|
579
581
|
} catch (claimErr) {
|
|
580
|
-
|
|
582
|
+
log.error('[gds] /box/scope claim-count read (non-fatal, → BASE)', claimErr && claimErr.message ? claimErr.message : claimErr);
|
|
581
583
|
hasActiveClaims = undefined;
|
|
582
584
|
}
|
|
583
585
|
}
|
|
@@ -594,7 +596,7 @@ module.exports = function buildBoxRouter() {
|
|
|
594
596
|
// an array). false → the rank fallback (no active claim / no lifecycle port).
|
|
595
597
|
return res.json({ ...meta, task_scope: Array.isArray(scopeKeys) });
|
|
596
598
|
} catch (err) {
|
|
597
|
-
|
|
599
|
+
log.error('[gds] GET /box/scope', err);
|
|
598
600
|
res.fail('box_scope_failed', { status: 500, message: 'internal error' });
|
|
599
601
|
}
|
|
600
602
|
});
|
|
@@ -618,7 +620,7 @@ module.exports = function buildBoxRouter() {
|
|
|
618
620
|
const state = await boxes.bumpActivity(pool, req.builder.id, { claudeActive });
|
|
619
621
|
res.json({ ok: true, state: state || 'none' });
|
|
620
622
|
} catch (err) {
|
|
621
|
-
|
|
623
|
+
log.error('[gds] POST /box/heartbeat', err);
|
|
622
624
|
res.fail('heartbeat_failed', { status: 500, message: 'internal error' });
|
|
623
625
|
}
|
|
624
626
|
});
|
|
@@ -653,7 +655,7 @@ module.exports = function buildBoxRouter() {
|
|
|
653
655
|
: 'A close request is already queued for your box.',
|
|
654
656
|
});
|
|
655
657
|
} catch (err) {
|
|
656
|
-
|
|
658
|
+
log.error('[gds] POST /box/close', err);
|
|
657
659
|
res.fail('close_failed', { status: 500, message: 'internal error' });
|
|
658
660
|
}
|
|
659
661
|
});
|
|
@@ -698,7 +700,7 @@ module.exports = function buildBoxRouter() {
|
|
|
698
700
|
key: { id: row.id, key_type: row.key_type, fingerprint: row.fingerprint, label: row.label },
|
|
699
701
|
});
|
|
700
702
|
} catch (err) {
|
|
701
|
-
|
|
703
|
+
log.error('[gds] POST /box/ssh-key', err);
|
|
702
704
|
res.fail('register_failed', { status: 500, message: 'internal error' });
|
|
703
705
|
}
|
|
704
706
|
});
|
|
@@ -714,7 +716,7 @@ module.exports = function buildBoxRouter() {
|
|
|
714
716
|
})),
|
|
715
717
|
});
|
|
716
718
|
} catch (err) {
|
|
717
|
-
|
|
719
|
+
log.error('[gds] GET /box/ssh-key', err);
|
|
718
720
|
res.fail('list_failed', { status: 500, message: 'internal error' });
|
|
719
721
|
}
|
|
720
722
|
});
|
|
@@ -730,7 +732,7 @@ module.exports = function buildBoxRouter() {
|
|
|
730
732
|
if (!removed) return res.fail('not_found', 404);
|
|
731
733
|
res.json({ ok: true, deleted: removed });
|
|
732
734
|
} catch (err) {
|
|
733
|
-
|
|
735
|
+
log.error('[gds] DELETE /box/ssh-key/:id', err);
|
|
734
736
|
res.fail('delete_failed', { status: 500, message: 'internal error' });
|
|
735
737
|
}
|
|
736
738
|
});
|
|
@@ -766,7 +768,7 @@ module.exports = function buildBoxRouter() {
|
|
|
766
768
|
await boxOnboard.touchSshKeysUsed(pool, req.builder.id).catch(() => {});
|
|
767
769
|
res.type('text/plain').send(boxOnboard.buildAuthorizedKeysFile(keys));
|
|
768
770
|
} catch (err) {
|
|
769
|
-
|
|
771
|
+
log.error('[gds] GET /box/authorized-keys', err);
|
|
770
772
|
res.fail('authorized_keys_failed', 500);
|
|
771
773
|
}
|
|
772
774
|
});
|
|
@@ -786,7 +788,7 @@ module.exports = function buildBoxRouter() {
|
|
|
786
788
|
if (err && (err.code === 'BAD_LOGIN' || err.code === 'BAD_HOSTNAME')) {
|
|
787
789
|
return res.fail('bad_identity', { status: 400, message: 'internal error' });
|
|
788
790
|
}
|
|
789
|
-
|
|
791
|
+
log.error('[gds] GET /box/managed-settings', err);
|
|
790
792
|
res.fail('managed_settings_failed', 500);
|
|
791
793
|
}
|
|
792
794
|
});
|
|
@@ -869,7 +871,7 @@ module.exports = function buildBoxRouter() {
|
|
|
869
871
|
: `A ${intent.action} is already queued for your box.`,
|
|
870
872
|
});
|
|
871
873
|
} catch (err) {
|
|
872
|
-
|
|
874
|
+
log.error('[gds] POST /box/ensure', err);
|
|
873
875
|
res.fail('ensure_failed', 500);
|
|
874
876
|
}
|
|
875
877
|
});
|
|
@@ -947,7 +949,7 @@ module.exports = function buildBoxRouter() {
|
|
|
947
949
|
: 'Box is up; waiting for the terminal service + tunnel to publish their URL (a few seconds after boot).',
|
|
948
950
|
});
|
|
949
951
|
} catch (err) {
|
|
950
|
-
|
|
952
|
+
log.error('[gds] GET /box/terminal', err);
|
|
951
953
|
res.fail('terminal_failed', 500);
|
|
952
954
|
}
|
|
953
955
|
});
|
|
@@ -983,7 +985,7 @@ module.exports = function buildBoxRouter() {
|
|
|
983
985
|
}
|
|
984
986
|
res.json({ ok: true, state });
|
|
985
987
|
} catch (err) {
|
|
986
|
-
|
|
988
|
+
log.error('[gds] POST /box/terminal', err);
|
|
987
989
|
res.fail('terminal_failed', 500);
|
|
988
990
|
}
|
|
989
991
|
});
|
|
@@ -1012,7 +1014,7 @@ module.exports = function buildBoxRouter() {
|
|
|
1012
1014
|
}
|
|
1013
1015
|
res.json({ ok: true, state, count: parsed.lines.length });
|
|
1014
1016
|
} catch (err) {
|
|
1015
|
-
|
|
1017
|
+
log.error('[gds] POST /box/host-keys', err);
|
|
1016
1018
|
res.fail('host_keys_failed', 500);
|
|
1017
1019
|
}
|
|
1018
1020
|
});
|
|
@@ -1049,7 +1051,7 @@ module.exports = function buildBoxRouter() {
|
|
|
1049
1051
|
}
|
|
1050
1052
|
res.json({ ok: true, state });
|
|
1051
1053
|
} catch (err) {
|
|
1052
|
-
|
|
1054
|
+
log.error('[gds] POST /box/version', err);
|
|
1053
1055
|
res.fail('version_report_failed', 500);
|
|
1054
1056
|
}
|
|
1055
1057
|
});
|