From 91ac1047c424d089b9879473123e43a06d77f9f6 Mon Sep 17 00:00:00 2001 From: Petrus Pennanen Date: Wed, 23 Sep 2026 13:03:38 +0200 Subject: [PATCH] test(uik): fake host telemetry sources in served-model tests On Linux, DesktopAdapter's heartbeat reads /proc through the default host-telemetry sources. A test machine that happens to run a llama-server published that model into every heartbeat the suite built, so 6 of 40 served-model tests failed on the M5 and passed everywhere else. DesktopAdapter now takes an injectable `hostSources` (as host-telemetry.js already does), and the served-model tests pass faked mac sources by default. Patch by @hermes (found and verified on the M5); applied and re-verified by @claudeMB with a simulated llama-server leak on macOS. Co-Authored-By: Claude Opus 5.5 --- packages/user-intent-kit/src/adapters/desktop.js | 10 +++++++++- packages/user-intent-kit/test/served-model.test.js | 7 +++++-- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/user-intent-kit/src/adapters/desktop.js b/packages/user-intent-kit/src/adapters/desktop.js index 71caf78..08e3611 100644 --- a/packages/user-intent-kit/src/adapters/desktop.js +++ b/packages/user-intent-kit/src/adapters/desktop.js @@ -24,6 +24,7 @@ export class DesktopAdapter { #kind; #model; #modelProbe; + #hostSources; #availabilityProbe; #pollIntervalMs; #publisher; @@ -43,11 +44,18 @@ export class DesktopAdapter { */ constructor(client, { pollIntervalMs = 30000, machine, kind, model, modelProbe, availabilityProbe, + hostSources, } = {}) { this.#client = client; this.#machine = machine ?? client?.deviceId ?? undefined; this.#kind = kind; this.#model = model; + // Telemetry sources are injectable for the same reason they are in + // host-telemetry.js: on Linux the default sources read /proc, and a test + // machine that happens to run a llama-server would publish its model into + // every heartbeat a test builds — passing suites that quietly depend on + // an empty machine are the same bug as skipped ones. + this.#hostSources = hostSources; // Order matters: the served-model probe's generation guard is wired to // the disk scan, so the scan has to exist first. Without the guard a probe // could ask a server to generate with a model that is half downloaded, @@ -189,7 +197,7 @@ export class DesktopAdapter { screen_active: active, context: active ? 'active' : 'idle', ...(idleSec === undefined ? {} : { idle_sec: idleSec }), - ...collectHostTelemetry({ machine: this.#machine, kind: this.#kind, model: this.#servedModel() }), + ...collectHostTelemetry({ machine: this.#machine, kind: this.#kind, model: this.#servedModel(), sources: this.#hostSources ?? undefined }), // The weaker claim, in its OWN keys. `model` still means served and // nothing else, so a dashboard that has never heard of availability // cannot start rendering "this box could run it" as "this box is diff --git a/packages/user-intent-kit/test/served-model.test.js b/packages/user-intent-kit/test/served-model.test.js index 2e34e1e..2ad1b20 100644 --- a/packages/user-intent-kit/test/served-model.test.js +++ b/packages/user-intent-kit/test/served-model.test.js @@ -264,7 +264,7 @@ test('a heartbeat publishes before the probe has answered anything', async () => patchDevice: async (state) => { patched.push(state); }, startHeartbeat() {}, stopHeartbeat() {}, }; - const desktop = new DesktopAdapter(client, { machine: 'macbook', modelProbe: probe, pollIntervalMs: 1e9 }); + const desktop = new DesktopAdapter(client, { machine: 'macbook', modelProbe: probe, pollIntervalMs: 1e9, hostSources: macSources() }); // The whole point: this awaits nothing on the network. await desktop.publishState(); @@ -623,7 +623,10 @@ async function stateFrom(opts) { patchDevice: async (state) => { patched.push(state); }, startHeartbeat() {}, stopHeartbeat() {}, }; - const desktop = new DesktopAdapter(client, { machine: 'testbox', pollIntervalMs: 1e9, ...opts }); + // Faked sources by default: on Linux the real ones read /proc, and a box that + // happens to run a llama-server would leak its model name into every test + // payload — the suite must say the same thing on every machine. + const desktop = new DesktopAdapter(client, { machine: 'testbox', pollIntervalMs: 1e9, hostSources: macSources(), ...opts }); await desktop.publishState(); desktop.stop(); return patched[0];