From 6b6dcf3a25a75c1b3df92fe3e4ec8ad9ae88c039 Mon Sep 17 00:00:00 2001 From: Tinson Lai Date: Fri, 7 Aug 2026 15:03:22 +0000 Subject: [PATCH 1/5] fix(onboard): accept the fixed llama.cpp loopback host port The managed installer pins the fixed loopback host port that every downstream llama.cpp endpoint assumes, while the lifecycle validator required a dynamic assignment, so managed onboarding always failed on the inspection that follows container creation. The validator now compares the configured host port against the port the bindings pin, and the lifecycle input requires that port instead of accepting a dynamic binding. Signed-off-by: Tinson Lai --- .../llama-cpp/host-local-runtime.test.ts | 10 ++++ .../llama-cpp/managed-installer.test.ts | 2 + ...docker-llama-cpp-managed-lifecycle.test.ts | 19 +++++-- .../docker-llama-cpp-managed-lifecycle.ts | 55 +++++++------------ .../runtime-provider/host-local-inference.ts | 2 +- 5 files changed, 48 insertions(+), 40 deletions(-) diff --git a/src/lib/inference/llama-cpp/host-local-runtime.test.ts b/src/lib/inference/llama-cpp/host-local-runtime.test.ts index 77f5c96b78b..4a17143f6bc 100644 --- a/src/lib/inference/llama-cpp/host-local-runtime.test.ts +++ b/src/lib/inference/llama-cpp/host-local-runtime.test.ts @@ -15,6 +15,7 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { LLAMA_CPP_PORT } from "./contract"; import { buildLlamaCppHostLocalDockerArgv, type LlamaCppHostLocalLaunchContract, @@ -159,6 +160,15 @@ describe("llama.cpp host-local runtime materializer", () => { expect(argv.join("\n")).not.toContain("huggingface.co"); }); + it("publishes the fixed loopback host port when the bindings pin one", () => { + const argv = buildLlamaCppHostLocalDockerArgv(contract(), { + ...bindings(), + hostPort: LLAMA_CPP_PORT, + }); + + expect(valuesAfter(argv, "--publish")).toEqual([`127.0.0.1:${String(LLAMA_CPP_PORT)}:8081`]); + }); + it("takes launch settings from the declared contract instead of code defaults (#8144)", () => { const input = contract(); const changed = { diff --git a/src/lib/inference/llama-cpp/managed-installer.test.ts b/src/lib/inference/llama-cpp/managed-installer.test.ts index f037dbfe96f..7774a9f264f 100644 --- a/src/lib/inference/llama-cpp/managed-installer.test.ts +++ b/src/lib/inference/llama-cpp/managed-installer.test.ts @@ -27,6 +27,7 @@ import { createPodmanRuntimeProviderBundle } from "../../onboard/runtime-provide import { isLlamaCppServingRecipe } from "../serving/adapter-registry"; import { loadManagedInferenceCatalog } from "../serving/catalog-loader"; import type { ResolvedLlamaCppInferenceSelection } from "../serving/types"; +import { LLAMA_CPP_PORT } from "./contract"; import { inspectManagedLlamaCppRuntimeExact, installManagedLlamaCpp, @@ -735,6 +736,7 @@ describe("managed llama.cpp installer", () => { expect(createLifecycle).toHaveBeenCalledWith( expect.objectContaining({ bindings: expect.objectContaining({ + hostPort: LLAMA_CPP_PORT, imageReference: selected.recipe.spec.runtime.image, }), contract: expect.objectContaining({ diff --git a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts index bc9c2b0ee89..13286354f6f 100644 --- a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts +++ b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts @@ -9,12 +9,12 @@ import path from "node:path"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import type { ContainerEngine } from "../../adapters/container-engine"; +import { LLAMA_CPP_PORT } from "../../inference/llama-cpp/contract"; import type { LlamaCppGgufCachePlan } from "../../inference/llama-cpp/gguf-cache-plan"; /* Test-only reconstruction of the exact immutable command for recovery fixtures. */ import { buildLlamaCppHostLocalServerArgv, type LlamaCppHostLocalLaunchContract, - type LlamaCppHostLocalRuntimeBindings, } from "../../inference/llama-cpp/host-local-runtime"; import { createDockerLlamaCppManagedLifecycle, @@ -32,6 +32,7 @@ import { } from "./host-local-inference"; import type { PersistedEngineAuthorityStore } from "./persisted-engine-authority"; +const HOST_PORT = String(LLAMA_CPP_PORT); const MODEL_DIGEST = `sha256:${"a".repeat(64)}`; const IMAGE = `ghcr.io/nvidia/nemoclaw/llama-cpp-server@sha256:${"c".repeat(64)}`; const PROBE_IMAGE = `quay.io/curl/curl@sha256:${"d".repeat(64)}`; @@ -231,10 +232,11 @@ function keyRootIdentitySha256(): string { }); } -function bindings(): LlamaCppHostLocalRuntimeBindings { +function bindings(): DockerLlamaCppManagedLifecycleOptions["bindings"] { return { apiKeyHostPath: apiKeyPath, containerName: "nemoclaw-llama-cpp", + hostPort: LLAMA_CPP_PORT, imageReference: IMAGE, model: { digest: MODEL_DIGEST, @@ -435,7 +437,7 @@ function dockerFixture(): DockerFixture { HostConfig: { NetworkMode: "nemoclaw-llama-cpp-internal", RestartPolicy: { Name: "unless-stopped", MaximumRetryCount: 0 }, - PortBindings: { "8081/tcp": [{ HostIp: "127.0.0.1", HostPort: "" }] }, + PortBindings: { "8081/tcp": [{ HostIp: "127.0.0.1", HostPort: HOST_PORT }] }, ReadonlyRootfs: !hardeningDrift, CapDrop: ["ALL"], SecurityOpt: ["no-new-privileges:true"], @@ -463,7 +465,7 @@ function dockerFixture(): DockerFixture { NetworkSettings: { Networks: { "nemoclaw-llama-cpp-internal": { NetworkID: networkId } }, Ports: { - "8081/tcp": startedOnce ? [{ HostIp: "127.0.0.1", HostPort: "49152" }] : null, + "8081/tcp": startedOnce ? [{ HostIp: "127.0.0.1", HostPort: HOST_PORT }] : null, }, }, Mounts: [ @@ -779,7 +781,7 @@ describe("dormant Docker llama.cpp managed lifecycle", () => { const receipt = lifecycle.start(writer); const serialized = serializeHostLocalInferenceReceipt(receipt); - expect(receipt.endpoint.port).toBe(49152); + expect(receipt.endpoint.port).toBe(LLAMA_CPP_PORT); expect(receipt.runtime).toMatchObject({ kind: "container", runtimeId: RUNTIME_ID, @@ -1403,6 +1405,13 @@ describe("dormant Docker llama.cpp managed lifecycle", () => { ); }); + it("rejects a container whose configured host port is not the bound host port", () => { + const lifecycle = createDockerLlamaCppManagedLifecycle( + options(dockerFixture(), journalStore(), { ...bindings(), hostPort: 18_081 }), + ); + expect(() => lifecycle.start(receiptWriter())).toThrow("not the bound host port"); + }); + it("rejects effective hardening drift after creation (#8395)", () => { const fixture = dockerFixture(); const lifecycle = controller(fixture); diff --git a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts index 5d9c87b6a1b..89b14cac3de 100644 --- a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts +++ b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts @@ -274,8 +274,9 @@ function parseLabels(value: unknown): Readonly> { function parseInspection( output: string, contract: LlamaCppHostLocalLaunchContract, - networkName: string, + bindings: DockerLlamaCppManagedLifecycleOptions["bindings"], ): DockerContainerInspection { + const networkName = bindings.network.name; let parsed: unknown; try { parsed = JSON.parse(output); @@ -308,13 +309,16 @@ function parseInspection( throw new Error("Docker llama.cpp container has unexpected configured ports."); } const configuredPort = record(configuredBindings[0], "Docker llama.cpp configured port"); - if (configuredPort.HostIp !== "127.0.0.1" || configuredPort.HostPort !== "") { + if (configuredPort.HostIp !== "127.0.0.1") { throw new Error("Docker llama.cpp configured host port is not loopback-only."); } - const bindings = ports[portKey]; + if (configuredPort.HostPort !== String(bindings.hostPort)) { + throw new Error("Docker llama.cpp configured host port is not the bound host port."); + } + const publishedBindings = ports[portKey]; const published = - Array.isArray(bindings) && bindings.length === 1 - ? record(bindings[0], "Docker llama.cpp published port") + Array.isArray(publishedBindings) && publishedBindings.length === 1 + ? record(publishedBindings[0], "Docker llama.cpp published port") : null; if (published !== null && published.HostIp !== "127.0.0.1") { throw new Error("Docker llama.cpp host port is not loopback-only."); @@ -423,7 +427,7 @@ function inspectContainer( engine: ContainerEngine, target: string, contract: LlamaCppHostLocalLaunchContract, - networkName: string, + bindings: DockerLlamaCppManagedLifecycleOptions["bindings"], ): DockerContainerInspection | null { const result = engine.capture(["container", "inspect", target], INSPECT_TIMEOUT_MS); const escapedTarget = target.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"); @@ -434,7 +438,7 @@ function inspectContainer( if (!result.error && result.status === 1 && exactAbsent.test(result.stderr.trim())) { return null; } - return parseInspection(requireSuccess("container inspection", result), contract, networkName); + return parseInspection(requireSuccess("container inspection", result), contract, bindings); } function currentUid(): bigint { @@ -915,12 +919,7 @@ function rollbackExact( return; } const target = record.runtimeId ?? record.containerName; - let container = inspectContainer( - options.engine, - target, - options.contract, - options.bindings.network.name, - ); + let container = inspectContainer(options.engine, target, options.contract, options.bindings); if (container === null && record.phase === "creating" && uncertainRecoveryUnixMs !== undefined) { if ( record.createIntentUnixMs === null || @@ -930,12 +929,7 @@ function rollbackExact( throw new Error("Docker llama.cpp uncertain create remains inside its absence grace period."); } options.journalStore.assertExecution(lease); - container = inspectContainer( - options.engine, - target, - options.contract, - options.bindings.network.name, - ); + container = inspectContainer(options.engine, target, options.contract, options.bindings); } if (container !== null) { const owned = requireOwnedContainer(container, options, record); @@ -943,14 +937,7 @@ function rollbackExact( "exact rollback", captureMutation(options, lease, execution, ["rm", "--force", owned.id], MUTATION_TIMEOUT_MS), ); - if ( - inspectContainer( - options.engine, - owned.id, - options.contract, - options.bindings.network.name, - ) !== null - ) { + if (inspectContainer(options.engine, owned.id, options.contract, options.bindings) !== null) { throw new Error("Docker llama.cpp exact rollback left the owned runtime present."); } } @@ -1205,7 +1192,7 @@ export function createDockerLlamaCppManagedLifecycle( options.engine, authorized.receipt.runtime.runtimeId, options.contract, - options.bindings.network.name, + options.bindings, ); if (inspected === null) throw new Error("Docker llama.cpp owned runtime is absent."); const container = requireOwnedContainer(inspected, options, authorized.journal); @@ -1322,7 +1309,7 @@ export function createDockerLlamaCppManagedLifecycle( options.engine, normalized.runtime.runtimeId, options.contract, - options.bindings.network.name, + options.bindings, ); const journal = options.journalStore.load(normalized.runtime.model.generation); if (existing !== null || journal !== null) authorizeReceipt(normalized, true); @@ -1337,7 +1324,7 @@ export function createDockerLlamaCppManagedLifecycle( options.engine, normalized.runtime.runtimeId, options.contract, - options.bindings.network.name, + options.bindings, ); if (existing === null) { const journal = options.journalStore.load(normalized.runtime.model.generation); @@ -1376,7 +1363,7 @@ export function createDockerLlamaCppManagedLifecycle( options.engine, inspected.container.id, options.contract, - options.bindings.network.name, + options.bindings, ) !== null ) { throw new Error("Docker llama.cpp removal left the exact runtime present."); @@ -1472,7 +1459,7 @@ export function createDockerLlamaCppManagedLifecycle( options.engine, options.bindings.containerName, options.contract, - options.bindings.network.name, + options.bindings, ) !== null ) { throw new Error("Docker llama.cpp container name is already in use."); @@ -1553,7 +1540,7 @@ export function createDockerLlamaCppManagedLifecycle( options.engine, options.bindings.containerName, options.contract, - options.bindings.network.name, + options.bindings, ); if (create.error || create.status !== 0 || created === null) { throw new Error( @@ -1579,7 +1566,7 @@ export function createDockerLlamaCppManagedLifecycle( options.engine, created.id, options.contract, - options.bindings.network.name, + options.bindings, ); if (started === null || !started.running) { throw new Error("Docker llama.cpp start did not leave the exact runtime running."); diff --git a/src/lib/onboard/runtime-provider/host-local-inference.ts b/src/lib/onboard/runtime-provider/host-local-inference.ts index db2f75a96ae..6d665b76b28 100644 --- a/src/lib/onboard/runtime-provider/host-local-inference.ts +++ b/src/lib/onboard/runtime-provider/host-local-inference.ts @@ -169,7 +169,7 @@ export interface HostLocalLlamaCppLifecycleInput { readonly authorityStore: PersistedEngineAuthorityStore; readonly apiKeyRootHostPath: string; readonly bindingSha256: string; - readonly bindings: LlamaCppHostLocalRuntimeBindings; + readonly bindings: LlamaCppHostLocalRuntimeBindings & { readonly hostPort: number }; readonly cacheRootHostPath: string; readonly contract: LlamaCppHostLocalLaunchContract; readonly engine: ContainerEngine; From c75c19b4c1f067cfc0293ecb01784be8eb9b6dea Mon Sep 17 00:00:00 2001 From: Apurv Kumaria Date: Fri, 7 Aug 2026 08:51:49 -0700 Subject: [PATCH 2/5] fix(onboard): clean up invalid llama.cpp ports Signed-off-by: Apurv Kumaria --- ...docker-llama-cpp-managed-lifecycle.test.ts | 8 +- .../docker-llama-cpp-managed-lifecycle.ts | 81 ++++++++++++------- 2 files changed, 58 insertions(+), 31 deletions(-) diff --git a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts index 13286354f6f..93f795ef2be 100644 --- a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts +++ b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts @@ -1405,11 +1405,15 @@ describe("dormant Docker llama.cpp managed lifecycle", () => { ); }); - it("rejects a container whose configured host port is not the bound host port", () => { + it("cleans up a post-create host-port mismatch and lets recovery converge", () => { + const [fixture, store] = [dockerFixture(), journalStore()] as const; const lifecycle = createDockerLlamaCppManagedLifecycle( - options(dockerFixture(), journalStore(), { ...bindings(), hostPort: 18_081 }), + options(fixture, store, { ...bindings(), hostPort: 18_081 }), ); expect(() => lifecycle.start(receiptWriter())).toThrow("not the bound host port"); + expect(store.list()).toEqual([]); + expect(lifecycle.recoverUnfinished(receiptWriter())).toEqual({ recovered: [], failures: [] }); + expect(controller(fixture, store).start(receiptWriter()).endpoint.port).toBe(LLAMA_CPP_PORT); }); it("rejects effective hardening drift after creation (#8395)", () => { diff --git a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts index 89b14cac3de..109a30035b5 100644 --- a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts +++ b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts @@ -118,6 +118,8 @@ interface DockerContainerInspection { }; } +type DockerContainerInspectionMode = "runtime" | "cleanup"; + interface StableFileIdentity { readonly dev: bigint; readonly ino: bigint; @@ -275,6 +277,7 @@ function parseInspection( output: string, contract: LlamaCppHostLocalLaunchContract, bindings: DockerLlamaCppManagedLifecycleOptions["bindings"], + mode: DockerContainerInspectionMode, ): DockerContainerInspection { const networkName = bindings.network.name; let parsed: unknown; @@ -298,30 +301,34 @@ function parseInspection( throw new Error("Docker llama.cpp container has unexpected network attachments."); } const attached = record(networks[networkName], "Docker llama.cpp network attachment"); - const ports = record(networkSettings.Ports, "Docker llama.cpp published ports"); - const portKey = `${String(contract.serve.port)}/tcp`; - const configuredPorts = record(hostConfig.PortBindings, "Docker llama.cpp configured ports"); - if (Object.keys(configuredPorts).length !== 1) { - throw new Error("Docker llama.cpp container has extra configured ports."); - } - const configuredBindings = configuredPorts[portKey]; - if (!Array.isArray(configuredBindings) || configuredBindings.length !== 1) { - throw new Error("Docker llama.cpp container has unexpected configured ports."); - } - const configuredPort = record(configuredBindings[0], "Docker llama.cpp configured port"); - if (configuredPort.HostIp !== "127.0.0.1") { - throw new Error("Docker llama.cpp configured host port is not loopback-only."); - } - if (configuredPort.HostPort !== String(bindings.hostPort)) { - throw new Error("Docker llama.cpp configured host port is not the bound host port."); - } - const publishedBindings = ports[portKey]; - const published = - Array.isArray(publishedBindings) && publishedBindings.length === 1 - ? record(publishedBindings[0], "Docker llama.cpp published port") - : null; - if (published !== null && published.HostIp !== "127.0.0.1") { - throw new Error("Docker llama.cpp host port is not loopback-only."); + let hostPort: number | null = null; + if (mode === "runtime") { + const ports = record(networkSettings.Ports, "Docker llama.cpp published ports"); + const portKey = `${String(contract.serve.port)}/tcp`; + const configuredPorts = record(hostConfig.PortBindings, "Docker llama.cpp configured ports"); + if (Object.keys(configuredPorts).length !== 1) { + throw new Error("Docker llama.cpp container has extra configured ports."); + } + const configuredBindings = configuredPorts[portKey]; + if (!Array.isArray(configuredBindings) || configuredBindings.length !== 1) { + throw new Error("Docker llama.cpp container has unexpected configured ports."); + } + const configuredPort = record(configuredBindings[0], "Docker llama.cpp configured port"); + if (configuredPort.HostIp !== "127.0.0.1") { + throw new Error("Docker llama.cpp configured host port is not loopback-only."); + } + if (configuredPort.HostPort !== String(bindings.hostPort)) { + throw new Error("Docker llama.cpp configured host port is not the bound host port."); + } + const publishedBindings = ports[portKey]; + const published = + Array.isArray(publishedBindings) && publishedBindings.length === 1 + ? record(publishedBindings[0], "Docker llama.cpp published port") + : null; + if (published !== null && published.HostIp !== "127.0.0.1") { + throw new Error("Docker llama.cpp host port is not loopback-only."); + } + hostPort = published === null ? null : exactPort(published.HostPort); } if (!Array.isArray(source.Mounts)) { throw new Error("Docker llama.cpp inspection returned malformed mounts."); @@ -390,7 +397,7 @@ function parseInspection( status: stateStatus, networkId: exactId(attached.NetworkID, "Docker attached network identity"), networkName, - hostPort: published === null ? null : exactPort(published.HostPort), + hostPort, mounts: Object.freeze(mounts), hardening: Object.freeze({ user: String(config.User ?? ""), @@ -428,6 +435,7 @@ function inspectContainer( target: string, contract: LlamaCppHostLocalLaunchContract, bindings: DockerLlamaCppManagedLifecycleOptions["bindings"], + mode: DockerContainerInspectionMode = "runtime", ): DockerContainerInspection | null { const result = engine.capture(["container", "inspect", target], INSPECT_TIMEOUT_MS); const escapedTarget = target.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&"); @@ -438,7 +446,7 @@ function inspectContainer( if (!result.error && result.status === 1 && exactAbsent.test(result.stderr.trim())) { return null; } - return parseInspection(requireSuccess("container inspection", result), contract, bindings); + return parseInspection(requireSuccess("container inspection", result), contract, bindings, mode); } function currentUid(): bigint { @@ -919,7 +927,13 @@ function rollbackExact( return; } const target = record.runtimeId ?? record.containerName; - let container = inspectContainer(options.engine, target, options.contract, options.bindings); + let container = inspectContainer( + options.engine, + target, + options.contract, + options.bindings, + "cleanup", + ); if (container === null && record.phase === "creating" && uncertainRecoveryUnixMs !== undefined) { if ( record.createIntentUnixMs === null || @@ -929,7 +943,13 @@ function rollbackExact( throw new Error("Docker llama.cpp uncertain create remains inside its absence grace period."); } options.journalStore.assertExecution(lease); - container = inspectContainer(options.engine, target, options.contract, options.bindings); + container = inspectContainer( + options.engine, + target, + options.contract, + options.bindings, + "cleanup", + ); } if (container !== null) { const owned = requireOwnedContainer(container, options, record); @@ -937,7 +957,10 @@ function rollbackExact( "exact rollback", captureMutation(options, lease, execution, ["rm", "--force", owned.id], MUTATION_TIMEOUT_MS), ); - if (inspectContainer(options.engine, owned.id, options.contract, options.bindings) !== null) { + if ( + inspectContainer(options.engine, owned.id, options.contract, options.bindings, "cleanup") !== + null + ) { throw new Error("Docker llama.cpp exact rollback left the owned runtime present."); } } From cd1ce157ad2f3fbaf8506e32aa99d80da3a9968f Mon Sep 17 00:00:00 2001 From: Apurv Kumaria Date: Fri, 7 Aug 2026 09:35:56 -0700 Subject: [PATCH 3/5] test(onboard): align llama.cpp port regressions Signed-off-by: Apurv Kumaria --- .../docker-llama-cpp-managed-lifecycle.test.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts index 82925032a55..a6f5d2f73f5 100644 --- a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts +++ b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts @@ -826,14 +826,14 @@ describe("dormant Docker llama.cpp managed lifecycle", () => { expect(lifecycle.runtime.destroy(receipt).status).toBe("already-absent"); }); it.each([ - ["configured", "8082", undefined], - ["published", "8081", "8082"], - ] as const)("rolls back exact ownership for %s loopback port drift (#8544)", (_kind, configured, published) => { + ["configured", "8082", undefined, /bound host port/u], + ["published", "8081", "8082", /declared binding/u], + ] as const)("rolls back exact ownership for %s loopback port drift (#8544)", (_kind, configured, published, expectedError) => { const [fixture, store] = [dockerFixture(configured, published), journalStore()]; const lifecycle = createDockerLlamaCppManagedLifecycle( options(fixture, store, { ...bindings(), hostPort: 8081 }), ); - expect(() => lifecycle.start(receiptWriter())).toThrow(/binding/u); + expect(() => lifecycle.start(receiptWriter())).toThrow(expectedError); const calls = fixture.capture.mock.calls.map((call) => call[0]); expect(calls).toContainEqual(["rm", "--force", RUNTIME_ID]); expect(calls).toContainEqual(["network", "rm", NETWORK_ID]); @@ -841,6 +841,7 @@ describe("dormant Docker llama.cpp managed lifecycle", () => { }); it("cleans up malformed or non-loopback published bindings after rejecting port drift (#8544)", () => { for (const args of [ + [HOST_PORT, HOST_PORT, "0.0.0.0", 1], ["8081", "8082", "0.0.0.0", 1], ["8081", "invalid", "127.0.0.1", 1], ["8081", "8082", "127.0.0.1", 2], From f15745eb0390fc18e68e1002f88245654851f514 Mon Sep 17 00:00:00 2001 From: Aaron Erickson Date: Fri, 7 Aug 2026 09:43:12 -0700 Subject: [PATCH 4/5] test(onboard): clarify llama.cpp binding coverage Signed-off-by: Aaron Erickson --- .../runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts index a6f5d2f73f5..885134b9dae 100644 --- a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts +++ b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.test.ts @@ -839,7 +839,7 @@ describe("dormant Docker llama.cpp managed lifecycle", () => { expect(calls).toContainEqual(["network", "rm", NETWORK_ID]); expect(store.list()).toEqual([]); }); - it("cleans up malformed or non-loopback published bindings after rejecting port drift (#8544)", () => { + it("rejects and cleans up malformed or non-loopback published bindings (#8544)", () => { for (const args of [ [HOST_PORT, HOST_PORT, "0.0.0.0", 1], ["8081", "8082", "0.0.0.0", 1], From 4428002419c20f543d528667572640a20e1d266a Mon Sep 17 00:00:00 2001 From: Aaron Erickson Date: Fri, 7 Aug 2026 09:58:18 -0700 Subject: [PATCH 5/5] chore(onboard): normalize lifecycle formatting Signed-off-by: Aaron Erickson --- .../docker-llama-cpp-managed-lifecycle.ts | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts index 97ab72529ef..23e387e2a39 100644 --- a/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts +++ b/src/lib/onboard/runtime-provider/docker-llama-cpp-managed-lifecycle.ts @@ -967,13 +967,8 @@ function rollbackExact( captureMutation(options, lease, execution, ["rm", "--force", owned.id], MUTATION_TIMEOUT_MS), ); if ( - inspectContainer( - options.engine, - owned.id, - options.contract, - options.bindings, - "cleanup", - ) !== null + inspectContainer(options.engine, owned.id, options.contract, options.bindings, "cleanup") !== + null ) { throw new Error("Docker llama.cpp exact rollback left the owned runtime present."); }