@bongos/core 1.19.743 → 1.19.744

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 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.743",
6
- "core_contract": "1.19.743",
7
- "source_commit": "ab27f1b16b14260ffd2f5ae8342504053928aa40",
5
+ "core_version": "1.19.744",
6
+ "core_contract": "1.19.744",
7
+ "source_commit": "a1c9e8b6b38e48c9f3a6040ff29b76ee3457b808",
8
8
  "source_ref": "HEAD",
9
- "built_at": "2026-09-15T14:55:42.206Z",
9
+ "built_at": "2026-09-15T15:04:25.874Z",
10
10
  "redaction": {
11
11
  "model": "docs-redacted+functional-verbatim",
12
12
  "docs_redacted": 479,
@@ -17,7 +17,7 @@
17
17
  "gate": "passed"
18
18
  },
19
19
  "file_count": 2611,
20
- "tree_sha256": "7eed1fd142643158bd9ddbb2f69beff6924a75e10c6b3ac121eb4c029787d4e5",
20
+ "tree_sha256": "4cfb37d1d47bb997d911c6ae24958d363737b154c725bfb76fb65f3e71c92449",
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": "97ecbfdf15f6707e5f4a0d46ce1597667e0fd592e1adf2d36f3cf006adf5d2ce"
2495
+ "sha256": "8f98164df753a9a4a8c77ade44d450eeb65eee2987dcc5b46d0d251f2a62d399"
2496
2496
  },
2497
2497
  {
2498
2498
  "path": "docs/modules-contract.md",
@@ -6257,7 +6257,7 @@
6257
6257
  {
6258
6258
  "path": "modules/provisioning/provisioning.js",
6259
6259
  "mode": "0000644",
6260
- "sha256": "18cb9676bd343e49873e2a3cface6d491aa59a840215531184b0d1863f3de271"
6260
+ "sha256": "9e6d1356fa046f97f3141c353302637dad2deed4c2460d124c8d7636b0ff0065"
6261
6261
  },
6262
6262
  {
6263
6263
  "path": "modules/provisioning/rate-limit.js",
@@ -6297,7 +6297,7 @@
6297
6297
  {
6298
6298
  "path": "modules/provisioning/tests/provisioning.mjs",
6299
6299
  "mode": "0000644",
6300
- "sha256": "904b1a6f8c704e606e7f93937465b14840857c287d31abda9d4772c528501f92"
6300
+ "sha256": "8fbac4b6857f7ccd1dab9355b01c2574c537196af8ec2755901189b14829fbe5"
6301
6301
  },
6302
6302
  {
6303
6303
  "path": "modules/provisioning/ui/.gitkeep",
@@ -7542,12 +7542,12 @@
7542
7542
  {
7543
7543
  "path": "package-lock.json",
7544
7544
  "mode": "0000644",
7545
- "sha256": "9b9d8bc2b152c80ee2cbe2c9ee8e235f0130fbc317e67b7b8cfedbfa806129c2"
7545
+ "sha256": "7d86631d2cad28001db3920822fd96bb638cede683d627fe0101445320c12d7e"
7546
7546
  },
7547
7547
  {
7548
7548
  "path": "package.json",
7549
7549
  "mode": "0000644",
7550
- "sha256": "b954e60f7093cbdd715857d5fed0f33c91e1f84fc4844714a59e9ab38669284d"
7550
+ "sha256": "d4c3e36f1af2829fc4bc7d9b6dc29be667c75e6d5fd870855398bc5e13380ddc"
7551
7551
  },
7552
7552
  {
7553
7553
  "path": "public-docs/index.html",
@@ -9347,7 +9347,7 @@
9347
9347
  {
9348
9348
  "path": "src/module-api.js",
9349
9349
  "mode": "0000644",
9350
- "sha256": "ff5ab852aa0fe991ee391e3ede0b07bf25316d90525e2c40ea9863ada99834e0"
9350
+ "sha256": "6cec169dc7c62404bb81e3b7fc00506de07048b3a0ce2ef59f892d467b9e0c3b"
9351
9351
  },
9352
9352
  {
9353
9353
  "path": "src/module-loader/catalog.js",
@@ -1960,5 +1960,7 @@ is load-bearing: the script throws rather than guess if it is missing, and
1960
1960
  landed since 1.19.741 with no explicit bump. run 34983109625. (task 1002620)
1961
1961
  1.19.743 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1962
1962
  landed since 1.19.742 with no explicit bump. run 34984876076. (task 1002620)
1963
+ 1.19.744 — CI auto-patch (publish-on-merge, ADR 0161): carrier for merges
1964
+ landed since 1.19.743 with no explicit bump. run 34985887902. (task 1002620)
1963
1965
  ---------------------------------------------------------------------------
1964
1966
  ```
@@ -275,6 +275,19 @@ const TIER_MONTHLY_USD = {
275
275
  's-4vcpu-8gb': 48,
276
276
  };
277
277
 
278
+ // The size the RUNNER actually creates when a dedicated instance names no tier
279
+ // (`scripts/gds/provision.js`: `size: inst.tier || 's-2vcpu-4gb'`). It lives here
280
+ // because costEstimateUsd has to agree with it: before task 1003692 the estimate
281
+ // treated an absent tier as unpriced and reported $0 for a droplet the runner was
282
+ // really billing at $24/mo, so the fleet cost ledger under-reported by the full
283
+ // cost of every tier-less dedicated instance.
284
+ //
285
+ // The runner cannot import this. `provision.js` is reachable from a generator's
286
+ // executed closure (via onboard.js) and tests/executed_closure.mjs pins how far
287
+ // that closure may grow, so a new require there is a test failure, not a tidy-up.
288
+ // `tests/provisioning.mjs` pins the two against each other instead.
289
+ const DEFAULT_DEDICATED_TIER = 's-2vcpu-4gb';
290
+
278
291
  // ---------------------------------------------------------------------------
279
292
  // Pure helpers (no I/O — exported for unit tests)
280
293
  // ---------------------------------------------------------------------------
@@ -295,7 +308,12 @@ function isValidSlug(slug) {
295
308
  // rate (0 if the tier is unknown/unset). PURE.
296
309
  function costEstimateUsd({ hostingShape, tier } = {}) {
297
310
  if (hostingShape !== 'dedicated') return 0;
298
- return TIER_MONTHLY_USD[tier] || 0;
311
+ // An ABSENT tier is not an unknown one. The runner substitutes its own default
312
+ // and bills for it, so the estimate has to price that same default or the ledger
313
+ // reports $0 for a real droplet (task 1003692). An unrecognised tier STILL falls
314
+ // through to 0 — unpriced rather than wrong, per the table's own note.
315
+ const effective = tier == null || tier === '' ? DEFAULT_DEDICATED_TIER : tier;
316
+ return TIER_MONTHLY_USD[effective] || 0;
299
317
  }
300
318
 
301
319
  // Normalize an SNI/hostname for an EXACT allow-list match: lowercase, trim, drop a
@@ -1427,7 +1445,7 @@ module.exports = {
1427
1445
  SETTINGS_VOCAB, DEFAULT_SETTINGS, SETTINGS_COMPANION_ENV, PROJECT_DETAIL_VOCAB, DESCRIPTION_MAX,
1428
1446
  PLANET_TEMPLATES, PLANET_ACCENTS, PLANET_VOCAB,
1429
1447
  // pure
1430
- isValidSlug, costEstimateUsd, publicInstance, normalizeHostname,
1448
+ isValidSlug, costEstimateUsd, DEFAULT_DEDICATED_TIER, publicInstance, normalizeHostname,
1431
1449
  defaultDomainForSlug, isReservedHostname, effectiveSettings, planetChoice,
1432
1450
  settingsPushOwed,
1433
1451
  // pure — the artist gate's non-retroactivity stamp (ADR 0241 §5, task 1003575)
@@ -9,6 +9,7 @@
9
9
 
10
10
  import { strict as assert } from 'node:assert';
11
11
  import { createRequire } from 'node:module';
12
+ import { readFileSync } from 'node:fs';
12
13
 
13
14
  const require = createRequire(import.meta.url);
14
15
  const P = require('../provisioning.js');
@@ -145,6 +146,51 @@ t('isValidSlug basic contract', () => {
145
146
  assert.equal(P.isValidSlug('a--b'), false); // double dash
146
147
  });
147
148
 
149
+ console.log('\ncostEstimateUsd — what a shape costs the fleet ledger (task 1003692):');
150
+
151
+ t('a dedicated instance is priced at its named tier', () => {
152
+ assert.equal(P.costEstimateUsd({ hostingShape: 'dedicated', tier: 's-1vcpu-1gb' }), 6);
153
+ assert.equal(P.costEstimateUsd({ hostingShape: 'dedicated', tier: 's-4vcpu-8gb' }), 48);
154
+ });
155
+
156
+ t('a dedicated instance with NO tier is priced at the runner default, not $0', () => {
157
+ // The bug: tier is optional on the create route, so it is commonly null, and the
158
+ // estimate used to read that as unpriced -> the ledger reported $0 for a droplet
159
+ // the runner really creates and bills. null, undefined and '' are all "not named".
160
+ for (const tier of [null, undefined, '']) {
161
+ assert.equal(P.costEstimateUsd({ hostingShape: 'dedicated', tier }), 24,
162
+ `a tier-less dedicated instance costs the default tier's price (tier=${JSON.stringify(tier)})`);
163
+ }
164
+ assert.equal(P.costEstimateUsd({ hostingShape: 'dedicated' }), 24, 'tier absent entirely');
165
+ });
166
+
167
+ t('an UNRECOGNISED tier is still $0 — unpriced rather than wrong', () => {
168
+ // Deliberately NOT folded into the default above. An absent tier is a known
169
+ // quantity (the runner substitutes one); an unknown string is not, and guessing
170
+ // a price for it would be inventing a number.
171
+ assert.equal(P.costEstimateUsd({ hostingShape: 'dedicated', tier: 's-99vcpu-1tb' }), 0);
172
+ });
173
+
174
+ t('every non-dedicated shape is $0 — it co-tenants on infrastructure already paid for', () => {
175
+ for (const shape of ['standalone', 'co-tenant', 'shared', undefined]) {
176
+ assert.equal(P.costEstimateUsd({ hostingShape: shape, tier: 's-4vcpu-8gb' }), 0,
177
+ `shape ${JSON.stringify(shape)} is never metered, whatever tier rides along`);
178
+ }
179
+ });
180
+
181
+ t('the estimate and the RUNNER agree on the default — they cannot import each other', () => {
182
+ // provision.js sits in a generator's executed closure (tests/executed_closure.mjs
183
+ // pins its size), so it cannot require this module for the constant. This pin is
184
+ // what stops the two literals drifting apart again.
185
+ const runner = readFileSync(new URL('../../../scripts/gds/provision.js', import.meta.url), 'utf8');
186
+ const m = runner.match(/size:\s*inst\.tier\s*\|\|\s*'([^']+)'/);
187
+ assert.ok(m, "provision.js no longer spells its default as `inst.tier || '<size>'` — re-pin this");
188
+ assert.equal(m[1], P.DEFAULT_DEDICATED_TIER,
189
+ 'the runner creates a different size than the ledger prices — the 1003692 bug, returning');
190
+ assert.ok(P.DEFAULT_DEDICATED_TIER in { 's-1vcpu-1gb': 1, 's-1vcpu-2gb': 1, 's-2vcpu-2gb': 1, 's-2vcpu-4gb': 1, 's-4vcpu-8gb': 1 },
191
+ 'the default tier must be one the price table knows, or the fix silently returns 0 again');
192
+ });
193
+
148
194
  console.log('\nGitHub App Manifest — pure builders (task 2080, ADR 0133):');
149
195
 
150
196
  t('githubAppName prefers the DOMAIN (unique + reads on the consent screen)', () => {
package/package-lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@bongos/core",
3
- "version": "1.19.743",
3
+ "version": "1.19.744",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@bongos/core",
9
- "version": "1.19.743",
9
+ "version": "1.19.744",
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.743",
3
+ "version": "1.19.744",
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/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.743'; // CI auto-patch carrier (ADR 0161); changelog: docs/module-api-changelog.md
74
+ const CORE_VERSION = '1.19.744'; // 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');