@bongos/core 1.24.76 → 1.24.77

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.
@@ -343,6 +343,49 @@ test('evaluate on a missing file is UNKNOWN — the CLI never defaults to go', (
343
343
  });
344
344
  });
345
345
 
346
+ // ── a device with no gauge at all (task 1005095) ────────────────────────────────
347
+ test('a caller that asks for it gets GO on a device with NO gauge file, marked as that kind of go', () => {
348
+ const d = decideCapacity({ gauge: null, now: NOW, config: { absentMeansGo: true } });
349
+ assert.equal(d.go, true, 'a PC set up five minutes ago has no gauge and never will; it must still start work');
350
+ assert.equal(d.unknown, false);
351
+ assert.equal(d.absent, true);
352
+ assert.equal(d.derived, true, 'so the log never mistakes it for a measured reading');
353
+ assert.match(d.reason, /no usage gauge on this device/);
354
+ });
355
+
356
+ test('absentMeansGo opens NOTHING but the missing file — every reading that cannot be vouched for still holds', () => {
357
+ for (const [label, g] of [
358
+ ['not an object', 'nonsense'],
359
+ ['no written_at', { five_hour: { used_percentage: 1, resets_at: NOW + HOUR } }],
360
+ ['neither window', { written_at: NOW }],
361
+ ['unparseable numbers', { written_at: NOW, five_hour: { used_percentage: 'lots', resets_at: 'soon' } }],
362
+ ['dated in the future', { ...gaugeAt(0), written_at: NOW + 600 }],
363
+ ['aged out inside a window still running', gaugeAt(4 * HOUR)],
364
+ ]) {
365
+ const d = decideCapacity({ gauge: g, now: NOW, config: { absentMeansGo: true } });
366
+ assert.equal(d.go, false, `${label} must still hold`);
367
+ assert.equal(d.unknown, true, `${label} must still read as unknown`);
368
+ }
369
+ // …and a real reading that says stop is obeyed exactly as before.
370
+ const spent = decideCapacity({ gauge: gaugeAt(30, { five_hour: { used_percentage: 99, resets_at: NOW + HOUR } }), now: NOW, config: { absentMeansGo: true } });
371
+ assert.equal(spent.go, false);
372
+ assert.equal(spent.unknown, false);
373
+ });
374
+
375
+ test('the supervisor passes absentMeansGo through evaluate; the bare CLI call does not', () => {
376
+ inTempGauge(() => {
377
+ const now = Math.floor(Date.now() / 1000);
378
+ assert.equal(cli.evaluate(now, { absentMeansGo: true }).decision.go, true);
379
+ assert.equal(cli.evaluate(now).decision.go, false);
380
+ // A file that is THERE but torn is a bad reading, not a missing gauge.
381
+ fs.mkdirSync(path.dirname(cli.gaugePath()), { recursive: true });
382
+ fs.writeFileSync(cli.gaugePath(), '{"written_at": 17');
383
+ const torn = cli.evaluate(now, { absentMeansGo: true }).decision;
384
+ assert.equal(torn.go, false, 'a half-written gauge file must hold, even for the supervisor');
385
+ assert.equal(torn.unknown, true);
386
+ });
387
+ });
388
+
346
389
  // --- a reading whose window has RESET is retired, not stale (task 1004178) ---
347
390
  //
348
391
  // An unattended host cannot refresh the gauge (see modules/autonomy/CLAUDE.md
@@ -142,6 +142,22 @@ test('the store anchor is FIXED, not brand-derived — that is the whole fix', (
142
142
  assert.ok(!/configHome|configDirName|safeBrand/.test(fn), `sessionStoreDir must not read the brand:\n${fn}`);
143
143
  });
144
144
 
145
+ test('BONGOS_CONFIG_ROOT moves the store with it, still at the fixed dir name (task 1005095)', () => {
146
+ // An Autobongos runner keeps its own login under its own root. The store must
147
+ // follow that root, or the runner would file its login into the builder's store.
148
+ const root = path.join(os.tmpdir(), 'cfg-root-probe');
149
+ const prev = process.env.BONGOS_CONFIG_ROOT;
150
+ process.env.BONGOS_CONFIG_ROOT = root;
151
+ try {
152
+ assert.equal(lib.sessionStoreDir(), path.join(path.resolve(root), ic.FALLBACK_DIR, 'instances'));
153
+ assert.equal(ic.configHome(), path.join(path.resolve(root), ic.configDirName()));
154
+ assert.ok(ic.configReadDirs().every((d) => d.startsWith(path.resolve(root) + path.sep)), 'no legacy dir under the home is read as a fallback');
155
+ } finally {
156
+ if (prev === undefined) delete process.env.BONGOS_CONFIG_ROOT; else process.env.BONGOS_CONFIG_ROOT = prev;
157
+ }
158
+ assert.equal(lib.sessionStoreDir(), path.join(os.homedir(), '.config', ic.FALLBACK_DIR, 'instances'), 'and back where it was without it');
159
+ });
160
+
145
161
  // ── 1b. The sandbox is really a sandbox ─────────────────────────────────────────────────────
146
162
  //
147
163
  // These guard the guard (task 1003760). Every test below writes to a session store, so if