@bongos/core 1.19.737 → 1.19.739
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 +27 -37
- package/docs/module-api-changelog.md +4 -0
- package/docs/recipes/private-npm-distribution.md +11 -11
- package/docs/recipes/upgrading-the-core.md +3 -2
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/go-live.js +18 -44
- package/scripts/gds/init.js +21 -29
- package/scripts/gds/package-core.js +7 -6
- package/scripts/gds/provision-config.js +0 -8
- package/scripts/gds/provision-repo.js +26 -30
- package/scripts/gds/provision.js +3 -5
- package/scripts/gds/start.js +1 -1
- package/scripts/gds/update-channel.js +3 -3
- package/scripts/gds/upgrade.js +17 -29
- package/src/module-api.js +1 -1
- package/tests/go_live.mjs +20 -19
- package/tests/init.mjs +11 -6
- package/tests/provision.mjs +33 -10
- package/tests/start_env_guard.mjs +8 -3
- package/tests/upgrade.mjs +6 -3
- package/scripts/gds/npmrc.js +0 -124
- package/tests/npmrc.mjs +0 -154
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.739",
|
|
6
|
+
"core_contract": "1.19.739",
|
|
7
|
+
"source_commit": "007654ffe674e9720a1e9227b87dc010b35178d9",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-14T11:30:11.483Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 479,
|
|
13
13
|
"agent_docs_stubbed": 24,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2107,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2610,
|
|
20
|
+
"tree_sha256": "387827a54efbdc59d0986629636d11366a72c83e8518a3f621bfffe13e020b61",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -2492,7 +2492,7 @@
|
|
|
2492
2492
|
{
|
|
2493
2493
|
"path": "docs/module-api-changelog.md",
|
|
2494
2494
|
"mode": "0000644",
|
|
2495
|
-
"sha256": "
|
|
2495
|
+
"sha256": "e1e65fc287020112074f69a451cba3e80b6c6e04ab746404c7a0db44f95f1c46"
|
|
2496
2496
|
},
|
|
2497
2497
|
{
|
|
2498
2498
|
"path": "docs/modules-contract.md",
|
|
@@ -2702,7 +2702,7 @@
|
|
|
2702
2702
|
{
|
|
2703
2703
|
"path": "docs/recipes/private-npm-distribution.md",
|
|
2704
2704
|
"mode": "0000644",
|
|
2705
|
-
"sha256": "
|
|
2705
|
+
"sha256": "6d488eff1dd8201debb991ba854c59b5404235b1a433403dbedecaf0638128e4"
|
|
2706
2706
|
},
|
|
2707
2707
|
{
|
|
2708
2708
|
"path": "docs/recipes/redteam-patrol.md",
|
|
@@ -2752,7 +2752,7 @@
|
|
|
2752
2752
|
{
|
|
2753
2753
|
"path": "docs/recipes/upgrading-the-core.md",
|
|
2754
2754
|
"mode": "0000644",
|
|
2755
|
-
"sha256": "
|
|
2755
|
+
"sha256": "3691b017562bde760fbe3ff29a5efb80d886dd770f1187dc4673459871cec513"
|
|
2756
2756
|
},
|
|
2757
2757
|
{
|
|
2758
2758
|
"path": "docs/recipes/windows-builders.md",
|
|
@@ -7537,12 +7537,12 @@
|
|
|
7537
7537
|
{
|
|
7538
7538
|
"path": "package-lock.json",
|
|
7539
7539
|
"mode": "0000644",
|
|
7540
|
-
"sha256": "
|
|
7540
|
+
"sha256": "f49b1b8e922b2717a695ddb091d8cb8e4f574634f2d6b57cb888a7a4dc7d38b0"
|
|
7541
7541
|
},
|
|
7542
7542
|
{
|
|
7543
7543
|
"path": "package.json",
|
|
7544
7544
|
"mode": "0000644",
|
|
7545
|
-
"sha256": "
|
|
7545
|
+
"sha256": "7f2a45d17d4d9dadcf80e5da376e648e607de28b3b8150fea3120e1dd4a3fee4"
|
|
7546
7546
|
},
|
|
7547
7547
|
{
|
|
7548
7548
|
"path": "public-docs/index.html",
|
|
@@ -8122,7 +8122,7 @@
|
|
|
8122
8122
|
{
|
|
8123
8123
|
"path": "scripts/gds/go-live.js",
|
|
8124
8124
|
"mode": "0000644",
|
|
8125
|
-
"sha256": "
|
|
8125
|
+
"sha256": "f246947d973eec84ea174736bc87bf52b4716c939fc86bff4037b330f6790f9a"
|
|
8126
8126
|
},
|
|
8127
8127
|
{
|
|
8128
8128
|
"path": "scripts/gds/goal-names.js",
|
|
@@ -8157,7 +8157,7 @@
|
|
|
8157
8157
|
{
|
|
8158
8158
|
"path": "scripts/gds/init.js",
|
|
8159
8159
|
"mode": "0000644",
|
|
8160
|
-
"sha256": "
|
|
8160
|
+
"sha256": "3879084ce7246d6fdcf3a053006e86e7d533016b6dbb9b5aa160d65a3e9336f5"
|
|
8161
8161
|
},
|
|
8162
8162
|
{
|
|
8163
8163
|
"path": "scripts/gds/install-git-hooks.js",
|
|
@@ -8299,11 +8299,6 @@
|
|
|
8299
8299
|
"mode": "0000644",
|
|
8300
8300
|
"sha256": "d34cbccec1fa3053f960c1ac0950ce7e6b4b05f9d32a23304c4c3abc41c22ef7"
|
|
8301
8301
|
},
|
|
8302
|
-
{
|
|
8303
|
-
"path": "scripts/gds/npmrc.js",
|
|
8304
|
-
"mode": "0000644",
|
|
8305
|
-
"sha256": "1beffeed111e8528cfa0a629d5ef81c766023de5c6820a81659a390070868228"
|
|
8306
|
-
},
|
|
8307
8302
|
{
|
|
8308
8303
|
"path": "scripts/gds/oauth-secret.js",
|
|
8309
8304
|
"mode": "0000644",
|
|
@@ -8332,7 +8327,7 @@
|
|
|
8332
8327
|
{
|
|
8333
8328
|
"path": "scripts/gds/package-core.js",
|
|
8334
8329
|
"mode": "0000644",
|
|
8335
|
-
"sha256": "
|
|
8330
|
+
"sha256": "d9a6748c0dadbff9954809df1c83345979e1356559312723e107f19949edfd7b"
|
|
8336
8331
|
},
|
|
8337
8332
|
{
|
|
8338
8333
|
"path": "scripts/gds/paste-token.js",
|
|
@@ -8362,7 +8357,7 @@
|
|
|
8362
8357
|
{
|
|
8363
8358
|
"path": "scripts/gds/provision-config.js",
|
|
8364
8359
|
"mode": "0000644",
|
|
8365
|
-
"sha256": "
|
|
8360
|
+
"sha256": "48d13ecda786629148713e0bd89f0d020ee47de107fa5a2327d44989783907ac"
|
|
8366
8361
|
},
|
|
8367
8362
|
{
|
|
8368
8363
|
"path": "scripts/gds/provision-net.js",
|
|
@@ -8377,7 +8372,7 @@
|
|
|
8377
8372
|
{
|
|
8378
8373
|
"path": "scripts/gds/provision-repo.js",
|
|
8379
8374
|
"mode": "0000644",
|
|
8380
|
-
"sha256": "
|
|
8375
|
+
"sha256": "c5822f3b29f90998c831639df2b0925033f17758cc329609de507f5e6e1ad7c8"
|
|
8381
8376
|
},
|
|
8382
8377
|
{
|
|
8383
8378
|
"path": "scripts/gds/provision-units.js",
|
|
@@ -8387,7 +8382,7 @@
|
|
|
8387
8382
|
{
|
|
8388
8383
|
"path": "scripts/gds/provision.js",
|
|
8389
8384
|
"mode": "0000644",
|
|
8390
|
-
"sha256": "
|
|
8385
|
+
"sha256": "614aa63d02f3ae97f39e492cb0948a92b40364e25f4780d87546b64c01e5c69c"
|
|
8391
8386
|
},
|
|
8392
8387
|
{
|
|
8393
8388
|
"path": "scripts/gds/publish-credential-check.js",
|
|
@@ -8857,7 +8852,7 @@
|
|
|
8857
8852
|
{
|
|
8858
8853
|
"path": "scripts/gds/start.js",
|
|
8859
8854
|
"mode": "0000644",
|
|
8860
|
-
"sha256": "
|
|
8855
|
+
"sha256": "7e4b7cd97e9a414cf55e1118c902b4ab17239d3810fe26e5b90aa18d6a948432"
|
|
8861
8856
|
},
|
|
8862
8857
|
{
|
|
8863
8858
|
"path": "scripts/gds/status.js",
|
|
@@ -8902,12 +8897,12 @@
|
|
|
8902
8897
|
{
|
|
8903
8898
|
"path": "scripts/gds/update-channel.js",
|
|
8904
8899
|
"mode": "0000644",
|
|
8905
|
-
"sha256": "
|
|
8900
|
+
"sha256": "1aeeb6171244e1d42ee7189a3aa2ae5d83fd175bfe1ce89300d6ca7511819f0b"
|
|
8906
8901
|
},
|
|
8907
8902
|
{
|
|
8908
8903
|
"path": "scripts/gds/upgrade.js",
|
|
8909
8904
|
"mode": "0000644",
|
|
8910
|
-
"sha256": "
|
|
8905
|
+
"sha256": "7a82fb0cf919e14700ceba718e28da1324df2eab669a847348271c85b2f7bd66"
|
|
8911
8906
|
},
|
|
8912
8907
|
{
|
|
8913
8908
|
"path": "scripts/gds/validate-design.js",
|
|
@@ -9347,7 +9342,7 @@
|
|
|
9347
9342
|
{
|
|
9348
9343
|
"path": "src/module-api.js",
|
|
9349
9344
|
"mode": "0000644",
|
|
9350
|
-
"sha256": "
|
|
9345
|
+
"sha256": "778ccc0ac1fe12d16e101aad85011d19d8fab03f00fa42fce71a26ec9b600fe2"
|
|
9351
9346
|
},
|
|
9352
9347
|
{
|
|
9353
9348
|
"path": "src/module-loader/catalog.js",
|
|
@@ -10567,7 +10562,7 @@
|
|
|
10567
10562
|
{
|
|
10568
10563
|
"path": "tests/go_live.mjs",
|
|
10569
10564
|
"mode": "0000644",
|
|
10570
|
-
"sha256": "
|
|
10565
|
+
"sha256": "fb937d66f8efa9fdcfb58715785a0c9d94e52034d04175aec78310c70bd53a7f"
|
|
10571
10566
|
},
|
|
10572
10567
|
{
|
|
10573
10568
|
"path": "tests/goal_abuse_matrix.mjs",
|
|
@@ -11287,7 +11282,7 @@
|
|
|
11287
11282
|
{
|
|
11288
11283
|
"path": "tests/init.mjs",
|
|
11289
11284
|
"mode": "0000644",
|
|
11290
|
-
"sha256": "
|
|
11285
|
+
"sha256": "945aaac204e9e60772d3e7b361c97c099d236e6be6b4b794cce36ecb391d8a1a"
|
|
11291
11286
|
},
|
|
11292
11287
|
{
|
|
11293
11288
|
"path": "tests/instance_config.mjs",
|
|
@@ -11679,11 +11674,6 @@
|
|
|
11679
11674
|
"mode": "0000644",
|
|
11680
11675
|
"sha256": "c57c0211709ab041ee895bbb4ade9f4b146b43147570bf282e6d6a808560db76"
|
|
11681
11676
|
},
|
|
11682
|
-
{
|
|
11683
|
-
"path": "tests/npmrc.mjs",
|
|
11684
|
-
"mode": "0000644",
|
|
11685
|
-
"sha256": "1aaa68ee1a4c4a58563cef86aac44cfa0e046ad7376d3a2108bf6dd455580942"
|
|
11686
|
-
},
|
|
11687
11677
|
{
|
|
11688
11678
|
"path": "tests/oauth_secret.mjs",
|
|
11689
11679
|
"mode": "0000644",
|
|
@@ -11982,7 +11972,7 @@
|
|
|
11982
11972
|
{
|
|
11983
11973
|
"path": "tests/provision.mjs",
|
|
11984
11974
|
"mode": "0000644",
|
|
11985
|
-
"sha256": "
|
|
11975
|
+
"sha256": "25fbd2adccf79e921c642f8f57b082f5f19fa01cd981cd5b813dc1070511aadb"
|
|
11986
11976
|
},
|
|
11987
11977
|
{
|
|
11988
11978
|
"path": "tests/provision_restart.mjs",
|
|
@@ -12702,7 +12692,7 @@
|
|
|
12702
12692
|
{
|
|
12703
12693
|
"path": "tests/start_env_guard.mjs",
|
|
12704
12694
|
"mode": "0000644",
|
|
12705
|
-
"sha256": "
|
|
12695
|
+
"sha256": "dd7171dbc59e024de99a063763219237814cf4c943fb3d873cc324f3bfde7f25"
|
|
12706
12696
|
},
|
|
12707
12697
|
{
|
|
12708
12698
|
"path": "tests/start_rebase_warning.mjs",
|
|
@@ -12922,7 +12912,7 @@
|
|
|
12922
12912
|
{
|
|
12923
12913
|
"path": "tests/upgrade.mjs",
|
|
12924
12914
|
"mode": "0000644",
|
|
12925
|
-
"sha256": "
|
|
12915
|
+
"sha256": "def73ab0f532c04df167d77917981eaf7e0dc7e1d2a7e7c85f3f962d7d65ce2a"
|
|
12926
12916
|
},
|
|
12927
12917
|
{
|
|
12928
12918
|
"path": "tests/upgrade_persist_pin.mjs",
|
|
@@ -1948,5 +1948,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
1948
1948
|
landed since 1.19.735 with no explicit bump. run 34771773838. (task 1002620)
|
|
1949
1949
|
1.19.737 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1950
1950
|
landed since 1.19.736 with no explicit bump. run 34795026282. (task 1002620)
|
|
1951
|
+
1.19.738 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1952
|
+
landed since 1.19.737 with no explicit bump. run 34797297122. (task 1002620)
|
|
1953
|
+
1.19.739 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
1954
|
+
landed since 1.19.738 with no explicit bump. run 34838475604. (task 1002620)
|
|
1951
1955
|
---------------------------------------------------------------------------
|
|
1952
1956
|
```
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|---|---|---|
|
|
15
15
|
| `@bongos/core` | the platform an instance installs + the `bongos` CLI (`bin`) | `bongos package-core` (`scripts/gds/package-core.js`) — synthesizes the package.json + a pruned lockfile, redacts, and packs a `.tgz` |
|
|
16
16
|
|
|
17
|
-
`@bongos/core` carries `publishConfig: { access: "
|
|
17
|
+
`@bongos/core` carries `publishConfig: { access: "public" }`, and `publishArgs` passes `--access public` as well — both, so neither drifting alone can silently take the package back to restricted ([ADR 0283](../adr/0283-the-core-publishes-publicly-because-access-was-never-the-thing-protecting-it.md)). It read `restricted` until 2026-09-13; what protects the artifact is the no-leak gate on the build, not who may fetch it.
|
|
18
18
|
|
|
19
19
|
The generated typed client (`node scripts/gds/gen-api-client.js` → `clients/bongos-client/`) is deliberately **not** in this table: it is not published, carries no `publishConfig`, and is consumed by vendoring. See its own README.
|
|
20
20
|
|
|
@@ -33,15 +33,15 @@ These involve payment and permanent, account-level actions. They are **not** don
|
|
|
33
33
|
Always preview with a dry-run first (no upload, no login needed):
|
|
34
34
|
|
|
35
35
|
```sh
|
|
36
|
-
# Core — build the tarball and DRY-RUN the
|
|
36
|
+
# Core — build the tarball and DRY-RUN the publish:
|
|
37
37
|
node scripts/gds/package-core.js --publish
|
|
38
38
|
```
|
|
39
39
|
|
|
40
|
-
Look for `
|
|
40
|
+
Look for `public access` and the `@bongos/core@<version>` line. When it looks right, publish for real (this is **permanent and public** — npm can't delete a name after 72h, and the version is never reusable):
|
|
41
41
|
|
|
42
42
|
```sh
|
|
43
43
|
npm login # once per machine (+ 2FA)
|
|
44
|
-
node scripts/gds/package-core.js --publish --live # actually publishes,
|
|
44
|
+
node scripts/gds/package-core.js --publish --live # actually publishes, PUBLIC
|
|
45
45
|
```
|
|
46
46
|
|
|
47
47
|
For the client (note the `./` — without it, npm reads the path as a git package spec, not a folder):
|
|
@@ -101,13 +101,13 @@ A tokenless registry `npm ci` 404s cleanly (`E404 … @bongos/core … could not
|
|
|
101
101
|
|
|
102
102
|
> **Proven end-to-end (2026-07-08, task 2118 / blocker 71).** A real `bongos init --registry-core` scaffold, with a valid read-only token in `NPM_TOKEN`, resolved `@bongos/core@1.17.0` straight from `registry.npmjs.org` and generated a reproducible `package-lock.json`. Both legs are confirmed: the registry pull works with a token and fails closed (404) without one. Provisioning still defaults to the vendored tarball until an owner explicitly sets `PROVISION_CORE_FROM_REGISTRY=1` on a live runner.
|
|
103
103
|
|
|
104
|
-
## Going public
|
|
104
|
+
## Going public — DONE 2026-09-13
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
`@bongos/core` is public ([ADR 0283](../adr/0283-the-core-publishes-publicly-because-access-was-never-the-thing-protecting-it.md), [task 1003872](https://cloudbongos.com/builders#/task/1003872)). `publishConfig.access` is `"public"` and the registry-side status was flipped with the one-time owner step:
|
|
107
107
|
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
108
|
+
```sh
|
|
109
|
+
npm access set status=public @bongos/core
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
That registry flip is separate from `--access public` on a publish, which governs only what *that* publish declares and is historically a no-op when re-publishing an already-private package. Verify the flip by a tokenless install from a clean `HOME`, not by the flag's presence. Public installs need no token; the paid private-package seats can be dropped.
|
|
113
113
|
- **Also publish the unscoped vanity name** for `npm install -g cloudbongos` — that is [task 2025](https://example.com/builders#/task/2025) (rename in `package-core.js`/`upgrade.js` + docs), done at launch.
|
|
@@ -108,7 +108,7 @@ node .claude/scheduled-tasks/core-update-subscription/subscribe.js #
|
|
|
108
108
|
node .claude/scheduled-tasks/core-update-subscription/subscribe.js --apply # upgrade
|
|
109
109
|
```
|
|
110
110
|
|
|
111
|
-
Each subscribed instance: read its installed core → ask the registry (`npm view`,
|
|
111
|
+
Each subscribed instance: read its installed core → ask the registry (`npm view`, no credential needed — the package is public) → resolve the newest version its channel permits → if newer, `bongos upgrade --to <v> --registry` with **auto-rollback ON**. It prints one line per instance plus a tally; a non-zero exit means an upgrade failed (already auto-reverted).
|
|
112
112
|
|
|
113
113
|
**Triple-gated, so nothing moves by accident:** the `core-update-subscription` routine is `requiresAutonomy: true` + **default OFF** in [`config/scheduled-routines.json`](../../config/scheduled-routines.json), the roster ships empty, and every upgrade is health-gated. Arm it by enabling the routine's timer on the control plane once autonomy is on.
|
|
114
114
|
|
|
@@ -116,7 +116,8 @@ Each subscribed instance: read its installed core → ask the registry (`npm vie
|
|
|
116
116
|
|
|
117
117
|
## Gotchas
|
|
118
118
|
|
|
119
|
-
- **`--registry` no
|
|
119
|
+
- **`--registry` needs no credential at all** (task 1003878). `@bongos/core` is **public** on npm (task 1003872), so `bongos upgrade --registry` resolves it from the default registry like any other dependency — no token, no login, and no instance `.npmrc`. An install failure on this path is therefore a *real* failure (network, registry outage, or a version that was never published), never a missing credential.
|
|
120
|
+
*History, so the symptom is recognisable on an old instance:* the core used to publish private, and the instance `.npmrc` read `_authToken=<redacted> npm gives that per-project key precedence, so with the env var unset it expanded EMPTY and **masked a perfectly valid literal token in `~/.npmrc`** — npm went anonymous, the private core 404'd, and the error blamed a credential the box actually held. Task 1002754 worked around it by resolving the token in-process; task 1003878 deleted the whole mechanism along with the `.npmrc` that caused it. An instance still carrying a committed `.npmrc` from a pre-1003878 scaffold can safely delete it.
|
|
120
121
|
- **A green `publish` run is not evidence of a publish.** The publish-on-merge lane succeeds on its no-op paths too (cascade terminator, armed-gate). Read the run's **job summary**, which now states the verdict explicitly: `PUBLISHED @bongos/core@<v>` vs `NO-OP — nothing was published this run`.
|
|
121
122
|
- **`PGDATABASE` is load-bearing on a co-tenant droplet.** `migrate.sh` defaults `PGDATABASE` to `example` — **production**. Always set `PGDATABASE=<instance-db>` explicitly, or you migrate the wrong database.
|
|
122
123
|
- **The health check polls the restart** (fixed in task [#1984](https://example.com/builders#/task/1984)). The service binds its port ~1s after `systemctl restart`, so `--health-url` now polls up to ~30s for a 2xx before reporting a warning — an immediate `fetch failed` no longer means a failed upgrade. (Pre-1984 cores fetched once and spuriously reported `fetch failed`; there, confirm with `is-active` + a manual `curl`.)
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.739",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@bongos/core",
|
|
9
|
-
"version": "1.19.
|
|
9
|
+
"version": "1.19.739",
|
|
10
10
|
"license": "AGPL-3.0-or-later",
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"express": "^4.21.2",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.739",
|
|
4
4
|
"description": "Cloud Bongos — the AI-first build platform core (GDS + platform surfaces + module system), installed as a versioned dependency (ADR 0108).",
|
|
5
5
|
"license": "AGPL-3.0-or-later",
|
|
6
6
|
"main": "src/platform-server.js",
|
package/scripts/gds/go-live.js
CHANGED
|
@@ -84,7 +84,7 @@ function isSafeToken(v) {
|
|
|
84
84
|
// unit name that the script would then try to `systemctl stop`. Absent, the stop and
|
|
85
85
|
// the restart are simply skipped: there is no `reset --hard` to race.
|
|
86
86
|
const REQUIRED_FIELDS = ['instanceDir', 'service', 'healthUrl', 'versionUrl'];
|
|
87
|
-
const OPTIONAL_FIELDS = ['ssh', 'local', 'deployTimer', 'deployService', '
|
|
87
|
+
const OPTIONAL_FIELDS = ['ssh', 'local', 'deployTimer', 'deployService', 'runAs', 'backupDb', 'backupDir', 'env', 'registryPackage', 'pinMode'];
|
|
88
88
|
|
|
89
89
|
// How the bump is made durable — the other half of co-tenant mode (task 1003521).
|
|
90
90
|
//
|
|
@@ -153,7 +153,6 @@ const CONFIG_TEMPLATE = `{
|
|
|
153
153
|
"versionUrl": "http://127.0.0.1:3002/version", // box-side truth read back after
|
|
154
154
|
"deployTimer": "my-deploy.timer", // optional: pull-deploy timer (its reset --hard is the hazard)
|
|
155
155
|
"deployService": "my-deploy.service", // optional: forced tick proves the pin stuck
|
|
156
|
-
"npmEnvFile": "/etc/my/npm.env", // optional: root-only NPM_TOKEN for a PRIVATE package
|
|
157
156
|
"runAs": "me", // optional: unprivileged owner of the instance
|
|
158
157
|
"backupDb": "mydb", // optional: pg_dump before the bump
|
|
159
158
|
"backupDir": "~/backups",
|
|
@@ -247,40 +246,19 @@ function remote(target, script, { run = spawnSync, timeoutMs = 900000 } = {}) {
|
|
|
247
246
|
// `sudo -u <user> -H env K=V … <cmd>` — the shape every runbook entry uses. Returns
|
|
248
247
|
// a string safe to embed because every component was allowlist-validated.
|
|
249
248
|
//
|
|
250
|
-
// A privileged child needs npm auth, and there is NO WAY to hand it a secret through
|
|
251
|
-
// sudo without logging it (task 1003218, corrected).
|
|
252
|
-
//
|
|
253
|
-
// `env NPM_TOKEN="$NPM_TOKEN" …` → sudo logs it in COMMAND=
|
|
254
|
-
// `sudo --preserve-env=NPM_TOKEN …` → sudo logs it in ENV=
|
|
255
|
-
//
|
|
256
|
-
// The first was the original bug; the second was my "fix", which only MOVED the value
|
|
257
|
-
// to a different field of the same log line. Both put a live credential in a
|
|
258
|
-
// persistent journal. What matters is that sudo logs its whole invocation, so the
|
|
259
|
-
// secret must never be part of it.
|
|
260
|
-
//
|
|
261
|
-
// So the child DERIVES the token itself, from a file it can already read. Only the
|
|
262
|
-
// `sed` appears in argv; the value never does. This is the shape docs/recipes/
|
|
263
|
-
// core-release-pipeline.md already documents as the safe one. The guard matters as
|
|
264
|
-
// much as the derivation: an EMPTY token silently sends npm to the public registry,
|
|
265
|
-
// which 404s the private package, which auto-rolls-back "cleanly" having taught you
|
|
266
|
-
// nothing — so an empty read aborts loudly instead of half-running.
|
|
267
|
-
//
|
|
268
|
-
// (The nightly lane never takes this path: it runs under systemd as the owner with an
|
|
269
|
-
// EnvironmentFile, no sudo, and leaks nothing. This is the manual/agent path only.)
|
|
270
|
-
const NPM_AUTH_PREAMBLE = [
|
|
271
|
-
'export NPM_TOKEN="${NPM_TOKEN:-$(sed -n \'s/.*_authToken=//p\' "$HOME/.npmrc" 2>/dev/null | head -1)}"',
|
|
272
|
-
'[ -n "$NPM_TOKEN" ] || { echo "go-live: EMPTY NPM_TOKEN — npm would 404 the private core and roll back; aborting" >&2; exit 12; }',
|
|
273
|
-
].join('; ');
|
|
274
|
-
|
|
275
249
|
// `sudo -u <user> -H env K=V … <cmd>` — the shape every runbook entry uses. Returns
|
|
276
250
|
// a string safe to embed because every component was allowlist-validated.
|
|
277
251
|
//
|
|
278
|
-
//
|
|
279
|
-
//
|
|
280
|
-
//
|
|
281
|
-
//
|
|
282
|
-
|
|
283
|
-
|
|
252
|
+
// Only NON-secret configuration (PGDATABASE, HOME) travels in the plain `env K=V` list —
|
|
253
|
+
// seeing those in a log is useful rather than harmful.
|
|
254
|
+
//
|
|
255
|
+
// This used to take a `needsNpm` option wrapping the command in a preamble that DERIVED an
|
|
256
|
+
// npm credential on the far side, because sudo logs its whole invocation and there was no way
|
|
257
|
+
// to hand a privileged child a secret without journalling it (task 1003218). @bongos/core is
|
|
258
|
+
// public (task 1003872), so the deploy path needs no npm credential at all and the whole
|
|
259
|
+
// hazard is gone rather than mitigated (task 1003878).
|
|
260
|
+
function asOwner(target, cmd) {
|
|
261
|
+
const inner = cmd;
|
|
284
262
|
const envPairs = Object.entries(target.env || {}).map(([k, v]) => `${k}=${v}`);
|
|
285
263
|
if (!target.runAs) {
|
|
286
264
|
const joined = envPairs.join(' ');
|
|
@@ -622,23 +600,21 @@ function renderReport(r) {
|
|
|
622
600
|
// Phases
|
|
623
601
|
// ---------------------------------------------------------------------------
|
|
624
602
|
|
|
625
|
-
// Registry proof + optional content proof, in ONE round-trip. The registry is
|
|
626
|
-
// consulted ON THE BOX because
|
|
627
|
-
//
|
|
603
|
+
// Registry proof + optional content proof, in ONE round-trip. The registry is still
|
|
604
|
+
// consulted ON THE BOX — not because auth lives there (the package is public now), but
|
|
605
|
+
// because the box's answer is the one that matters: its network, its resolver, its cache.
|
|
628
606
|
function probeRemote(target, targetVersion, marker, opts = {}) {
|
|
629
607
|
const pkg = target.registryPackage || '@bongos/core';
|
|
630
|
-
const src = target.npmEnvFile ? `set -a; . ${target.npmEnvFile}; set +a` : 'true';
|
|
631
608
|
const script = `
|
|
632
609
|
set -uo pipefail
|
|
633
|
-
${src}
|
|
634
610
|
echo "##REGISTRY##"
|
|
635
|
-
${asOwner(target, `npm view ${pkg}@${targetVersion} version
|
|
611
|
+
${asOwner(target, `npm view ${pkg}@${targetVersion} version`)} 2>&1 | tail -1
|
|
636
612
|
echo "##TREE##"
|
|
637
613
|
( cd ${target.instanceDir} && ${target.runAs ? `sudo -u ${target.runAs} -H ` : ''}git status --porcelain | head -20 )
|
|
638
614
|
echo "##INSTALLED##"
|
|
639
615
|
${asOwner(target, `node -e "console.log(require('${target.instanceDir}/node_modules/${pkg}/package.json').version)"`)} 2>&1 | tail -1
|
|
640
616
|
${marker ? `echo "##MARKER##"
|
|
641
|
-
${asOwner(target, `sh -c ${shq(markerProbe(pkg, targetVersion, marker))}
|
|
617
|
+
${asOwner(target, `sh -c ${shq(markerProbe(pkg, targetVersion, marker))}`)}` : ''}
|
|
642
618
|
echo "##END##"
|
|
643
619
|
`;
|
|
644
620
|
const res = remote(target, script, opts);
|
|
@@ -709,7 +685,6 @@ function applyGoLive(target, targetName, targetVersion, from, opts = {}) {
|
|
|
709
685
|
const pkg = target.registryPackage || '@bongos/core';
|
|
710
686
|
const pinMode = pinModeOf(target);
|
|
711
687
|
const steps = [];
|
|
712
|
-
const src = target.npmEnvFile ? `set -a; . ${target.npmEnvFile}; set +a` : 'true';
|
|
713
688
|
|
|
714
689
|
// Phase A — stop the pull-deploy timer, then back up. The timer's `reset --hard`
|
|
715
690
|
// is the hazard: it would revert an uncommitted pin mid-flight. A co-tenant has no
|
|
@@ -738,8 +713,7 @@ echo "##END##"
|
|
|
738
713
|
const upgrade = upgradeCommand(target, targetVersion);
|
|
739
714
|
const phaseB = remote(target, `
|
|
740
715
|
set -uo pipefail
|
|
741
|
-
${
|
|
742
|
-
${asOwner(target, `bash -c "cd ${target.instanceDir} && ${upgrade}"`, { needsNpm: true })}
|
|
716
|
+
${asOwner(target, `bash -c "cd ${target.instanceDir} && ${upgrade}"`)}
|
|
743
717
|
`, opts);
|
|
744
718
|
const rolledBack = /rolled back/i.test(phaseB.stdout + phaseB.stderr);
|
|
745
719
|
steps.push({
|
|
@@ -995,7 +969,7 @@ if (require.main === module) {
|
|
|
995
969
|
module.exports = {
|
|
996
970
|
loadConfig, selectTarget, validateTarget, planGoLive, artistGateEntries, readArtistGate, ARTIST_GATE_PATH, ARTIST_GATE_LEVELS,
|
|
997
971
|
parseMarker, parseMarkerHits,
|
|
998
|
-
renderPlan, renderReport, failureExcerpt, asOwner, isSafeToken,
|
|
972
|
+
renderPlan, renderReport, failureExcerpt, asOwner, isSafeToken, refreshMain, isLocalTarget, gitRefExists, SUDO_PREAMBLE,
|
|
999
973
|
applyGoLive, upgradeCommand, pinStep, pinModeOf,
|
|
1000
974
|
CONFIG_TEMPLATE, HALTS, SEMVER_RE, PIN_MODES, DEFAULT_PIN_MODE,
|
|
1001
975
|
};
|
package/scripts/gds/init.js
CHANGED
|
@@ -59,13 +59,13 @@
|
|
|
59
59
|
// bongos init --vendor-core <tgz> greenfield only: vendor the @bongos/core .tgz + pin
|
|
60
60
|
// package.json to file:vendor/… + generate package-lock.json,
|
|
61
61
|
// so the scaffold is `npm ci`-installable (ADR 0108 gap 1/4).
|
|
62
|
-
// Without it the scaffold pins the caret range
|
|
63
|
-
// resolves from the
|
|
64
|
-
// bongos init --registry-core greenfield only: keep the caret pin
|
|
65
|
-
// .
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
//
|
|
62
|
+
// Without it the scaffold pins the caret range, which
|
|
63
|
+
// resolves from the public npm registry (--registry-core).
|
|
64
|
+
// bongos init --registry-core greenfield only: keep the caret pin and generate
|
|
65
|
+
// package-lock.json from the registry. @bongos/core is
|
|
66
|
+
// PUBLIC (task 1003872), so this needs no token, no login
|
|
67
|
+
// and no .npmrc — it resolves from the default registry
|
|
68
|
+
// like any other dependency.
|
|
69
69
|
// Mutually exclusive with --vendor-core (registry vs tarball).
|
|
70
70
|
|
|
71
71
|
const fs = require('node:fs');
|
|
@@ -78,7 +78,6 @@ const { materializeClaude } = require('./claude-materialize'); // ADR 0108 §3 (
|
|
|
78
78
|
const { detectStack, formatStackSummary } = require('./adopt-detect'); // ADR 0121 §Decision 4 (task 2043): inspect an existing repo before layering
|
|
79
79
|
const { resolveBacklogTasks, DEFAULT_MAX: BACKLOG_MAX } = require('./adopt-import'); // ADR 0121 §Decision 3 (task 2044): import an existing backlog
|
|
80
80
|
const { preflightAdopt, formatPreflight } = require('./adopt-preflight'); // ADR 0121 §Decision 5 (task 2045): the accept-gated conflict pre-flight
|
|
81
|
-
const { writeNpmrc, hasNpmToken } = require('./npmrc'); // ADR 0134 (task 2090): the registry-install path's env-fed .npmrc
|
|
82
81
|
|
|
83
82
|
const KNOWN_MODULES = ['game', 'art-pipeline', 'discord', 'dev-box'];
|
|
84
83
|
|
|
@@ -946,7 +945,7 @@ async function main(argv) {
|
|
|
946
945
|
const adopt = hasFlag('--adopt', args); // brownfield: LAYER onto an existing repo (ADR 0121)
|
|
947
946
|
const accept = hasFlag('--accept', args) || hasFlag('--yes', args) || hasFlag('-y', args); // adopt pre-flight accept-gate (§Decision 5)
|
|
948
947
|
const vendorCore = arg('--vendor-core', args); // greenfield: vendor + file:-pin a core .tgz, then generate the lockfile (ADR 0108 gap 1/4, task 2053)
|
|
949
|
-
const registryCore = hasFlag('--registry-core', args); // greenfield: caret pin
|
|
948
|
+
const registryCore = hasFlag('--registry-core', args); // greenfield: keep the caret pin and generate the lockfile from the public registry (task 1003878)
|
|
950
949
|
|
|
951
950
|
if (adopt && force) {
|
|
952
951
|
console.error('init: --force is a greenfield-only overwrite; --adopt never overwrites, so --force is ignored.');
|
|
@@ -1030,30 +1029,23 @@ async function main(argv) {
|
|
|
1030
1029
|
}
|
|
1031
1030
|
}
|
|
1032
1031
|
|
|
1033
|
-
// Registry-install path
|
|
1034
|
-
//
|
|
1035
|
-
//
|
|
1036
|
-
//
|
|
1037
|
-
//
|
|
1038
|
-
//
|
|
1032
|
+
// Registry-install path: keep the caret pin writeConfigs wrote and generate
|
|
1033
|
+
// package-lock.json from the registry, so a later `npm ci` is reproducible.
|
|
1034
|
+
//
|
|
1035
|
+
// This used to write an env-fed npm auth file and skip the lockfile when no credential was
|
|
1036
|
+
// present, because @bongos/core published PRIVATE. It is public now (task 1003872), so it
|
|
1037
|
+
// resolves from the default registry like any other dependency: no auth file, no credential,
|
|
1038
|
+
// and no tokenless-404 branch to explain (task 1003878).
|
|
1039
1039
|
if (registryCore) {
|
|
1040
1040
|
if (dryRun) {
|
|
1041
|
-
console.log(
|
|
1042
|
-
? 'run `npm install` to generate package-lock.json from the registry'
|
|
1043
|
-
: 'SKIP lockfile generation (no NPM_TOKEN — the private core 404s until one is provided)'}`);
|
|
1041
|
+
console.log('\n[dry-run] would run `npm install` to generate package-lock.json from the registry');
|
|
1044
1042
|
} else {
|
|
1045
|
-
console.log('\nWiring the registry-install path
|
|
1046
|
-
|
|
1047
|
-
if (
|
|
1048
|
-
|
|
1049
|
-
if (!inst.ok) {
|
|
1050
|
-
console.error(` ! npm install failed (${inst.reason || 'exit ' + inst.code}) — confirm NPM_TOKEN reaches the private @bongos org; package-lock.json not generated.`);
|
|
1051
|
-
} else {
|
|
1052
|
-
console.log(' ✓ npm install → package-lock.json generated (pulled @bongos/core from the registry)');
|
|
1053
|
-
}
|
|
1043
|
+
console.log('\nWiring the registry-install path:');
|
|
1044
|
+
const inst = upgrade.npmInstall(dir);
|
|
1045
|
+
if (!inst.ok) {
|
|
1046
|
+
console.error(` ! npm install failed (${inst.reason || 'exit ' + inst.code}) — package-lock.json not generated. @bongos/core is public, so this is a real failure (network, registry outage, or an unpublished version), not a missing credential.`);
|
|
1054
1047
|
} else {
|
|
1055
|
-
console.log('
|
|
1056
|
-
console.log(' Provide a read-only automation token (paid `bongos` org) as NPM_TOKEN before `npm ci`; without it the private package 404s cleanly.');
|
|
1048
|
+
console.log(' ✓ npm install → package-lock.json generated (pulled @bongos/core from the registry)');
|
|
1057
1049
|
}
|
|
1058
1050
|
}
|
|
1059
1051
|
}
|
|
@@ -580,7 +580,8 @@ function publishArgs(tgzPath, live) {
|
|
|
580
580
|
|
|
581
581
|
// Publish (or dry-run) the built .tgz to npm. Auth is npm's own concern — this
|
|
582
582
|
// never holds a token; it shells out to `npm publish` and the owner's `npm login`
|
|
583
|
-
//
|
|
583
|
+
// provides it. The package is PUBLIC (task 1003872, ADR 0283), so no paid org plan
|
|
584
|
+
// is involved — a public scoped publish needs none.
|
|
584
585
|
// The child's stdout is routed to OUR stderr so main()'s machine-readable pin on
|
|
585
586
|
// stdout stays clean for CI capture.
|
|
586
587
|
function publishTarball({ tgzPath, live }) {
|
|
@@ -589,16 +590,16 @@ function publishTarball({ tgzPath, live }) {
|
|
|
589
590
|
console.error(`[package-core] ${live ? 'PUBLISH (permanent)' : 'publish DRY-RUN'} → ${NPM_BIN} ${args.join(' ')}`);
|
|
590
591
|
if (!live) {
|
|
591
592
|
console.error(' Dry-run: nothing is uploaded. To publish for real: re-run with --publish --live.');
|
|
592
|
-
console.error(' That is PERMANENT and
|
|
593
|
-
console.error('
|
|
593
|
+
console.error(' That is PERMANENT and PUBLIC (ADR 0283) — anyone can fetch it, and a version is never');
|
|
594
|
+
console.error(' reusable once taken. It requires `npm login`; no paid org plan (the package is public).');
|
|
594
595
|
}
|
|
595
596
|
const r = spawnSync(NPM_BIN, args, { cwd: REPO_ROOT, stdio: ['inherit', process.stderr, 'inherit'] });
|
|
596
597
|
if (r.error || r.status !== 0) {
|
|
597
598
|
console.error(`[package-core] npm publish ${live ? '' : '--dry-run '}FAILED (${r.error ? r.error.message : `exit ${r.status}`}).`);
|
|
598
|
-
if (live) console.error(' Common causes: not logged in (`npm login`),
|
|
599
|
+
if (live) console.error(' Common causes: not logged in (`npm login`), no publish rights on the @bongos scope, that version already taken, or 2FA.');
|
|
599
600
|
process.exit(r.status || 1);
|
|
600
601
|
}
|
|
601
|
-
console.error(`[package-core] npm publish ${live ? 'succeeded — @bongos/core is live
|
|
602
|
+
console.error(`[package-core] npm publish ${live ? 'succeeded — @bongos/core is live and PUBLIC on the registry.' : 'dry-run OK — the tarball is publishable.'}`);
|
|
602
603
|
}
|
|
603
604
|
|
|
604
605
|
// The neutral FLOOR — customer-zero identity tokens a portable core must never carry (task 1002220
|
|
@@ -1048,7 +1049,7 @@ module.exports = {
|
|
|
1048
1049
|
isAgentDoc, CORE_AGENT_DOC_STUB,
|
|
1049
1050
|
// task 1882 (ADR 0108 §2) — the real installable npm package
|
|
1050
1051
|
CORE_DEP_NAMES, buildPackageJson, resolveLockDep, lockfileClosure, prunePackageLock,
|
|
1051
|
-
// task 2089 (ADR 0134) —
|
|
1052
|
+
// task 2089 (ADR 0134) — the npm publish argv; PUBLIC since task 1003872 / ADR 0283
|
|
1052
1053
|
publishArgs,
|
|
1053
1054
|
// task 1002218 (audit H3) — build-time self-verify (reproduce pin + optional bare-install boot)
|
|
1054
1055
|
selfVerify, reproducePinFromTree,
|
|
@@ -19,12 +19,6 @@ const REPO_ROOT = path.resolve(__dirname, '..', '..');
|
|
|
19
19
|
// plain require (its require.main guard means importing it runs no CLI).
|
|
20
20
|
const oauthSecret = require('./oauth-secret');
|
|
21
21
|
|
|
22
|
-
// The registry-install gates + env-fed .npmrc (ADR 0134, task 2090). Lets the
|
|
23
|
-
// standalone scaffold OPT IN to pulling the PRIVATE @bongos/core from the npm
|
|
24
|
-
// registry (PROVISION_CORE_FROM_REGISTRY=1) instead of vendoring a tarball, with a
|
|
25
|
-
// fail-soft fallback to the vendored path when no NPM_TOKEN is present.
|
|
26
|
-
const { registryCoreRequested, hasNpmToken } = require('./npmrc');
|
|
27
|
-
|
|
28
22
|
// The HTTP User-Agent the manifest conversion stamps its GitHub call with (GitHub
|
|
29
23
|
// requires a UA). Overridable so a fork can identify itself; not secret.
|
|
30
24
|
const MANIFEST_UA = process.env.PROVISION_GITHUB_UA || 'cloudbongos-provisioner';
|
|
@@ -195,10 +189,8 @@ module.exports = {
|
|
|
195
189
|
REPO_ROOT,
|
|
196
190
|
coreVersionSafe,
|
|
197
191
|
hasFlag,
|
|
198
|
-
hasNpmToken,
|
|
199
192
|
loadDeps,
|
|
200
193
|
numEnv,
|
|
201
194
|
oauthSecret,
|
|
202
195
|
provisionerBotEmail,
|
|
203
|
-
registryCoreRequested,
|
|
204
196
|
};
|