@bongos/core 1.19.766 → 1.19.768
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 +19 -14
- package/docs/file-map.md +1 -0
- package/docs/module-api-changelog.md +4 -0
- package/package-lock.json +2 -2
- package/package.json +1 -1
- package/scripts/gds/backup-dropin-sweep.sh +95 -0
- package/scripts/gds/provision.js +2 -3
- package/src/module-api.js +1 -1
- package/tests/provision.mjs +12 -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.768",
|
|
6
|
+
"core_contract": "1.19.768",
|
|
7
|
+
"source_commit": "ec2107bdda1e0c2ee8404d14e539b83a836f767d",
|
|
8
8
|
"source_ref": "HEAD",
|
|
9
|
-
"built_at": "2026-09-
|
|
9
|
+
"built_at": "2026-09-16T14:46:45.582Z",
|
|
10
10
|
"redaction": {
|
|
11
11
|
"model": "docs-redacted+functional-verbatim",
|
|
12
12
|
"docs_redacted": 483,
|
|
13
13
|
"agent_docs_stubbed": 25,
|
|
14
|
-
"functional_verbatim":
|
|
14
|
+
"functional_verbatim": 2123,
|
|
15
15
|
"rules": 3,
|
|
16
16
|
"gate_literals": 3,
|
|
17
17
|
"gate": "passed"
|
|
18
18
|
},
|
|
19
|
-
"file_count":
|
|
20
|
-
"tree_sha256": "
|
|
19
|
+
"file_count": 2631,
|
|
20
|
+
"tree_sha256": "9d2871bffc966902b2a18d7c59fc92a2e5ea137e0bee5675716ca3fbee9e01ef",
|
|
21
21
|
"files": [
|
|
22
22
|
{
|
|
23
23
|
"path": ".claude/skills/ask-for-help/SKILL.md",
|
|
@@ -2502,7 +2502,7 @@
|
|
|
2502
2502
|
{
|
|
2503
2503
|
"path": "docs/file-map.md",
|
|
2504
2504
|
"mode": "0000644",
|
|
2505
|
-
"sha256": "
|
|
2505
|
+
"sha256": "9369c319c356283bdce655d126e78f339c9a329ecefc02d17c2997c45e583475"
|
|
2506
2506
|
},
|
|
2507
2507
|
{
|
|
2508
2508
|
"path": "docs/handoff-template.md",
|
|
@@ -2512,7 +2512,7 @@
|
|
|
2512
2512
|
{
|
|
2513
2513
|
"path": "docs/module-api-changelog.md",
|
|
2514
2514
|
"mode": "0000644",
|
|
2515
|
-
"sha256": "
|
|
2515
|
+
"sha256": "5c95283ebfac1200dcabcba2fa712b6b041be345412b92cd1f896e3648d9ecd0"
|
|
2516
2516
|
},
|
|
2517
2517
|
{
|
|
2518
2518
|
"path": "docs/modules-contract.md",
|
|
@@ -7577,12 +7577,12 @@
|
|
|
7577
7577
|
{
|
|
7578
7578
|
"path": "package-lock.json",
|
|
7579
7579
|
"mode": "0000644",
|
|
7580
|
-
"sha256": "
|
|
7580
|
+
"sha256": "4f7ef5cc202176fb1c83a20baea17017b6adb0892051832a4bd6a440d57f1fcc"
|
|
7581
7581
|
},
|
|
7582
7582
|
{
|
|
7583
7583
|
"path": "package.json",
|
|
7584
7584
|
"mode": "0000644",
|
|
7585
|
-
"sha256": "
|
|
7585
|
+
"sha256": "ee2355bc92153c9c139cf79e19f22b80dda73a5a2abdd102b67830cb3bee0d14"
|
|
7586
7586
|
},
|
|
7587
7587
|
{
|
|
7588
7588
|
"path": "public-docs/index.html",
|
|
@@ -7754,6 +7754,11 @@
|
|
|
7754
7754
|
"mode": "0000644",
|
|
7755
7755
|
"sha256": "4646bd6da8be2d2c40c1063bba47f5fdce0f2f63143e26fc16e36ea941adbc88"
|
|
7756
7756
|
},
|
|
7757
|
+
{
|
|
7758
|
+
"path": "scripts/gds/backup-dropin-sweep.sh",
|
|
7759
|
+
"mode": "0000644",
|
|
7760
|
+
"sha256": "bfbac57a3e282e1b482a967733eb8f39a15d97ffc8c24b4348370e4a11acc160"
|
|
7761
|
+
},
|
|
7757
7762
|
{
|
|
7758
7763
|
"path": "scripts/gds/backup.js",
|
|
7759
7764
|
"mode": "0000644",
|
|
@@ -8437,7 +8442,7 @@
|
|
|
8437
8442
|
{
|
|
8438
8443
|
"path": "scripts/gds/provision.js",
|
|
8439
8444
|
"mode": "0000644",
|
|
8440
|
-
"sha256": "
|
|
8445
|
+
"sha256": "bf403052607f7cce560633fc11d03f51ecf1e9fc1d32e4d6c601c6406787a143"
|
|
8441
8446
|
},
|
|
8442
8447
|
{
|
|
8443
8448
|
"path": "scripts/gds/publish-credential-check.js",
|
|
@@ -9397,7 +9402,7 @@
|
|
|
9397
9402
|
{
|
|
9398
9403
|
"path": "src/module-api.js",
|
|
9399
9404
|
"mode": "0000644",
|
|
9400
|
-
"sha256": "
|
|
9405
|
+
"sha256": "163989f8fd93a919241ac12e7627303618fc6d2d47b75f79e1b6fb875874a534"
|
|
9401
9406
|
},
|
|
9402
9407
|
{
|
|
9403
9408
|
"path": "src/module-loader/catalog.js",
|
|
@@ -12057,7 +12062,7 @@
|
|
|
12057
12062
|
{
|
|
12058
12063
|
"path": "tests/provision.mjs",
|
|
12059
12064
|
"mode": "0000644",
|
|
12060
|
-
"sha256": "
|
|
12065
|
+
"sha256": "5f7ec2483f8564dc9561f0becdfc36166bca5021b7f964db6d6e40d62108e041"
|
|
12061
12066
|
},
|
|
12062
12067
|
{
|
|
12063
12068
|
"path": "tests/provision_restart.mjs",
|
package/docs/file-map.md
CHANGED
|
@@ -187,6 +187,7 @@
|
|
|
187
187
|
│ ├── seed-v3-tasks.js ← V3 Planning Session #1: 80 net-new GDS-V3 tasks (V3.R01–V3.R89) + 10 idea_inbox promotions; idempotent on source_ref
|
|
188
188
|
│ ├── backfill-cost.js ← read art ledger → POST /api/gds/cost (idempotent)
|
|
189
189
|
│ ├── smoke-write.sh ← write-path smoke (create→claim→ship round-trip)
|
|
190
|
+
│ ├── backup-dropin-sweep.sh ← (task 1003930) control-plane sweep: retires the temporary task-1003925 backup drop-in from each project whose pinned core carries the fix (1.19.750+), proving one backup succeeds without it first; survey by default, `--apply` to act; re-run after each pin moves
|
|
190
191
|
│ ├── smoke-gds.js ← public-surface + 401-check smoke test (asserts /api/pms/* now 404s — removed in V3.R01-followup #308)
|
|
191
192
|
│ ├── box.js ← (#598/ADR 0031) per-builder dev box lifecycle CLI: provision·park·wake·deprovision·sweep-idle·sweep-dormant·status (dry-run default, --apply to act; rank-gated)
|
|
192
193
|
│ ├── smoke-box.sh ← (#598) hermetic box-lifecycle smoke (no DB/DO/network): runs tests/boxes.mjs + tests/cf_tunnel.mjs (#771 named tunnel) + route-rank + module-load
|
|
@@ -2006,5 +2006,9 @@ is load-bearing: the script throws rather than guess if it is missing, and
|
|
|
2006
2006
|
landed since 1.19.764 with no explicit bump. run 35102327521. (task 1002620)
|
|
2007
2007
|
1.19.766 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2008
2008
|
landed since 1.19.765 with no explicit bump. run 35104246900. (task 1002620)
|
|
2009
|
+
1.19.767 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2010
|
+
landed since 1.19.766 with no explicit bump. run 35109111074. (task 1002620)
|
|
2011
|
+
1.19.768 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
|
|
2012
|
+
landed since 1.19.767 with no explicit bump. run 35110800163. (task 1002620)
|
|
2009
2013
|
---------------------------------------------------------------------------
|
|
2010
2014
|
```
|
package/package-lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bongos/core",
|
|
3
|
-
"version": "1.19.
|
|
3
|
+
"version": "1.19.768",
|
|
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.768",
|
|
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.768",
|
|
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",
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/gds/backup-dropin-sweep.sh — retire the TEMPORARY task-1003925 backup drop-ins
|
|
3
|
+
# once a project's pinned core carries the fix (task 1003930, ADR 0285 follow-up).
|
|
4
|
+
#
|
|
5
|
+
# WHY. Before the nightly-backup fix (task 1003925, core 1.19.750) reached any
|
|
6
|
+
# project, the 10 live project backup units on the control plane got a systemd
|
|
7
|
+
# drop-in — /etc/systemd/system/<slug>-db-backup.service.d/task-1003925-min-bytes.conf
|
|
8
|
+
# (the backup script's min-bytes override, `*_BACKUP_MIN_BYTES=4096`) — so their
|
|
9
|
+
# small-but-valid dumps stopped being rejected.
|
|
10
|
+
# That workaround lives outside every repo, nothing removes it, and while it stays it
|
|
11
|
+
# hides whether the shipped fix actually works per project. Projects move to the fixed
|
|
12
|
+
# core one pin at a time, so this is a SWEEP to re-run after each pin moves, not a
|
|
13
|
+
# one-shot: each run retires only the drop-ins whose project can prove it no longer
|
|
14
|
+
# needs one (a backup run succeeds without it), and names the rest.
|
|
15
|
+
#
|
|
16
|
+
# Run on the control plane as a sudoer:
|
|
17
|
+
# bash scripts/gds/backup-dropin-sweep.sh # survey only — read-only, no sudo writes
|
|
18
|
+
# bash scripts/gds/backup-dropin-sweep.sh --apply # retire the eligible drop-ins + clear ghosts
|
|
19
|
+
#
|
|
20
|
+
# --apply, per eligible project (pinned core >= FIX_VERSION and drop-in present):
|
|
21
|
+
# rm the drop-in, daemon-reload, `systemctl start <slug>-db-backup.service`, wait for it,
|
|
22
|
+
# and require exit 0 AND a new dump under /var/backups/gds — else the drop-in is put back
|
|
23
|
+
# and the project is reported, so a project is never left with no backup at all.
|
|
24
|
+
# Then: `systemctl reset-failed` on any *-db-backup unit whose files are gone (a torn-down
|
|
25
|
+
# project's ghost; teardown removes the files but not the failed state — task 1003940).
|
|
26
|
+
set -uo pipefail
|
|
27
|
+
|
|
28
|
+
FIX_VERSION="${FIX_VERSION:-1.19.750}"
|
|
29
|
+
DROPIN=task-1003925-min-bytes.conf
|
|
30
|
+
BACKUP_DIR=/var/backups/gds
|
|
31
|
+
APPLY=0; [ "${1:-}" = "--apply" ] && APPLY=1
|
|
32
|
+
|
|
33
|
+
# The safety copies of retired drop-ins live in a root-owned, mode-0700, mktemp-named
|
|
34
|
+
# dir for the length of one run — never a predictable /tmp/<slug> path a lower-privileged
|
|
35
|
+
# local account could pre-stage a symlink at (CWE-377 / CWE-367 on a shared box). Created
|
|
36
|
+
# only under --apply; removed on exit whatever happened.
|
|
37
|
+
WORK=""
|
|
38
|
+
if [ "$APPLY" = 1 ]; then
|
|
39
|
+
WORK=$(sudo -n mktemp -d /var/tmp/backup-dropin-sweep.XXXXXX) || { echo "cannot create a root-owned work dir"; exit 1; }
|
|
40
|
+
trap 'sudo -n rm -rf "$WORK"' EXIT
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# The project's pinned core version: the installed inner manifest under its own checkout.
|
|
44
|
+
core_of() {
|
|
45
|
+
local slug=$1 pj
|
|
46
|
+
for pj in "/srv/cloudbongos/$slug/node_modules/@bongos/core/package.json" "/home/lars/$slug/node_modules/@bongos/core/package.json"; do
|
|
47
|
+
if sudo -n test -r "$pj"; then sudo -n node -e "console.log(require(process.argv[1]).version)" "$pj" 2>/dev/null && return; fi
|
|
48
|
+
done
|
|
49
|
+
echo "unknown"
|
|
50
|
+
}
|
|
51
|
+
# semver-ish: is $1 >= $2 ? (sort -V puts the smaller first)
|
|
52
|
+
at_least() { [ "$(printf '%s\n%s\n' "$1" "$2" | sort -V | head -1)" = "$2" ]; }
|
|
53
|
+
# The slug rides as a positional argument, never interpolated into the sh -c string.
|
|
54
|
+
dump_count() { sudo -n sh -c 'ls "$1"-*.sql.gz 2>/dev/null | wc -l' _ "$BACKUP_DIR/$1"; }
|
|
55
|
+
|
|
56
|
+
retired=(); kept=(); failed=()
|
|
57
|
+
echo "== drop-ins vs pinned core (fix = $FIX_VERSION) =="
|
|
58
|
+
for d in /etc/systemd/system/*-db-backup.service.d; do
|
|
59
|
+
[ -f "$d/$DROPIN" ] || continue
|
|
60
|
+
unit=$(basename "$d" .service.d); slug=${unit%-db-backup}
|
|
61
|
+
core=$(core_of "$slug")
|
|
62
|
+
if [ "$core" != "unknown" ] && at_least "$core" "$FIX_VERSION"; then verdict="ELIGIBLE"; else verdict="keeps drop-in"; fi
|
|
63
|
+
printf ' %-24s core=%-10s %s\n' "$slug" "$core" "$verdict"
|
|
64
|
+
if [ "$verdict" != "ELIGIBLE" ]; then kept+=("$slug ($core)"); continue; fi
|
|
65
|
+
[ "$APPLY" = 1 ] || { retired+=("$slug (would retire)"); continue; }
|
|
66
|
+
before=$(dump_count "$slug")
|
|
67
|
+
sudo -n cp "$d/$DROPIN" "$WORK/$slug.conf"
|
|
68
|
+
sudo -n rm -f "$d/$DROPIN"; sudo -n rmdir "$d" 2>/dev/null || true
|
|
69
|
+
sudo -n systemctl daemon-reload
|
|
70
|
+
# Type=oneshot (provision-units.js backupService): `start` blocks until the dump script exits.
|
|
71
|
+
sudo -n systemctl start "$unit.service"
|
|
72
|
+
after=$(dump_count "$slug")
|
|
73
|
+
if systemctl show -p Result --value "$unit.service" | grep -qx success && [ "$after" -gt "$before" ]; then
|
|
74
|
+
retired+=("$slug ($core; dumps $before→$after)")
|
|
75
|
+
else
|
|
76
|
+
sudo -n install -D -m 0644 "$WORK/$slug.conf" "$d/$DROPIN"; sudo -n systemctl daemon-reload
|
|
77
|
+
failed+=("$slug ($core; backup did not succeed without it — drop-in restored)")
|
|
78
|
+
fi
|
|
79
|
+
done
|
|
80
|
+
|
|
81
|
+
echo; echo "== failed *-db-backup units (ghosts of torn-down projects) =="
|
|
82
|
+
ghosts=$(systemctl --failed --no-legend 2>/dev/null | awk '/db-backup/ {print $1 == "●" ? $2 : $1}')
|
|
83
|
+
if [ -z "$ghosts" ]; then echo " (none)"; else
|
|
84
|
+
for u in $ghosts; do
|
|
85
|
+
if [ -e "/etc/systemd/system/$u" ]; then echo " $u: unit file still present — a real failure, not a ghost; left alone"; continue; fi
|
|
86
|
+
if [ "$APPLY" = 1 ]; then sudo -n systemctl reset-failed "$u" && echo " $u: ghost cleared"; else echo " $u: ghost (would reset-failed)"; fi
|
|
87
|
+
done
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
echo; echo "== summary =="
|
|
91
|
+
echo " retired (${#retired[@]}): ${retired[*]:-none}"
|
|
92
|
+
echo " kept (${#kept[@]}): ${kept[*]:-none}"
|
|
93
|
+
echo " failed (${#failed[@]}): ${failed[*]:-none}"
|
|
94
|
+
[ "$APPLY" = 1 ] || echo " (survey only — re-run with --apply to act)"
|
|
95
|
+
[ "${#failed[@]}" -eq 0 ]
|
package/scripts/gds/provision.js
CHANGED
|
@@ -1033,12 +1033,11 @@ async function teardownInstance(inst, deps) {
|
|
|
1033
1033
|
if (inst.hosting_shape !== 'dedicated') {
|
|
1034
1034
|
boxExec(`${sudoP}systemctl disable --now ${inst.slug}`, { allowFail: true });
|
|
1035
1035
|
boxExec(`${sudoP}rm -f ${serviceUnitPath(inst)}`, { allowFail: true });
|
|
1036
|
-
// Stop + remove the nightly backup units too (task 2213)
|
|
1037
|
-
// dumps are left in place — like the DB below, they are precious data a teardown
|
|
1038
|
-
// must not silently destroy.
|
|
1036
|
+
// Stop + remove the nightly backup units too (task 2213; the dir + dumps stay — precious data, like the DB below), then reset-failed (task 1003940): a removed unit's FAILED state outlives its file, so `systemctl --failed` listed torn-down ghosts for weeks.
|
|
1039
1037
|
boxExec(`${sudoP}systemctl disable --now ${backupUnitName(inst)}.timer`, { allowFail: true });
|
|
1040
1038
|
boxExec(`${sudoP}rm -f ${backupServicePath(inst)} ${backupTimerPath(inst)}`, { allowFail: true });
|
|
1041
1039
|
boxExec(`${sudoP}systemctl daemon-reload`, { allowFail: true });
|
|
1040
|
+
boxExec(`${sudoP}systemctl reset-failed ${inst.slug}.service ${backupUnitName(inst)}.service`, { allowFail: true });
|
|
1042
1041
|
// Left for an operator (data is precious), naming ONLY what this row created —
|
|
1043
1042
|
// teardown now takes 'requested'/'error'. `port` + `domain` stay held: ADR 0181.
|
|
1044
1043
|
const dumps = inst.db_name ? [`dropdb ${dbName(inst)}`, `prune ${CONFIG.backupDir}/${dbName(inst)}-*.sql.gz`] : [];
|
package/src/module-api.js
CHANGED
|
@@ -71,7 +71,7 @@ const { responsibilityFor, ROLE_RESPONSIBILITIES } = require('./role-responsibil
|
|
|
71
71
|
// there. scripts/gds/bump-version.js still rewrites the literal below; it appends
|
|
72
72
|
// the entry to that file. Look for a version's history there, not here.
|
|
73
73
|
// ---------------------------------------------------------------------------
|
|
74
|
-
const CORE_VERSION = '1.19.
|
|
74
|
+
const CORE_VERSION = '1.19.768'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
|
|
75
75
|
|
|
76
76
|
// A namespaced logger so a module's log lines are attributable + consistent.
|
|
77
77
|
// Usage: const log = api.logger('dev-box'); log.info('mounted');
|
package/tests/provision.mjs
CHANGED
|
@@ -1485,6 +1485,18 @@ await ta('teardownInstance(privileged): systemctl + rm-under-/etc are sudo-prefi
|
|
|
1485
1485
|
// task 2213: the backup units come down too (the dumps + dir are left in place)
|
|
1486
1486
|
assert.match(joined, /sudo systemctl disable --now mercury-db-backup\.timer/);
|
|
1487
1487
|
assert.match(joined, /sudo rm -f \/etc\/systemd\/system\/mercury-db-backup\.service \/etc\/systemd\/system\/mercury-db-backup\.timer/);
|
|
1488
|
+
// task 1003940: a removed unit's FAILED state outlives its file — clear it, AFTER the rm + reload,
|
|
1489
|
+
// for both the instance unit and its backup unit (the two ghosts task 1003930 found on the box).
|
|
1490
|
+
assert.match(joined, /sudo systemctl reset-failed mercury\.service mercury-db-backup\.service/);
|
|
1491
|
+
const idx = (re) => cmds.findIndex((c) => re.test(c));
|
|
1492
|
+
assert.ok(idx(/rm -f .*mercury-db-backup\.service/) < idx(/daemon-reload/), 'rm before reload');
|
|
1493
|
+
assert.ok(idx(/daemon-reload/) < idx(/reset-failed/), 'reset-failed after the reload that forgets the file — reset first and the stopped unit could fail again');
|
|
1494
|
+
});
|
|
1495
|
+
|
|
1496
|
+
await ta('teardownInstance(dedicated): no systemd steps at all, so no reset-failed either (its own droplet)', async () => {
|
|
1497
|
+
const { deps, cmds } = recorder();
|
|
1498
|
+
await P.teardownInstance({ ...coTenant, hosting_shape: 'dedicated', droplet_id: 9 }, deps);
|
|
1499
|
+
assert.ok(!cmds.some((c) => /reset-failed|daemon-reload|disable --now/.test(c)), cmds.join(' | '));
|
|
1488
1500
|
});
|
|
1489
1501
|
|
|
1490
1502
|
await ta('teardownInstance(default): NO sudo (bare, unchanged)', async () => {
|