fix: project runner skills into dev containers
This commit is contained in:
@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { collectSkillAvailability, collectSkillSyncPreflight } from "../src/components/microservices/code-queue/src/skill-availability";
|
||||
import { buildDevContainerPlan, configureProviderRuntime, providerRuntimeForTest } from "../src/components/microservices/code-queue/src/provider-runtime";
|
||||
import { codexPrPreflightQueryForTest } from "./src/code-queue";
|
||||
import { summarizeMicroserviceObservation } from "./src/microservices";
|
||||
|
||||
@@ -71,6 +72,9 @@ assertCondition(!docsReference.includes(forbiddenPathLiteral), "reference docs m
|
||||
assertCondition(countOccurrences(productionManifest, "name: UNIDESK_SKILLS_PATH") === 3, "production read/write/scheduler must set UNIDESK_SKILLS_PATH", {
|
||||
count: countOccurrences(productionManifest, "name: UNIDESK_SKILLS_PATH"),
|
||||
});
|
||||
assertCondition(countOccurrences(productionManifest, "name: CODE_QUEUE_RUNNER_SKILLS_SOURCE_PATH") === 3, "production read/write/scheduler must expose the approved runner skills source path", {
|
||||
count: countOccurrences(productionManifest, "name: CODE_QUEUE_RUNNER_SKILLS_SOURCE_PATH"),
|
||||
});
|
||||
assertCondition(countOccurrences(productionManifest, "mountPath: /root/.agents/skills") === 3, "production read/write/scheduler must mount skills target", {
|
||||
count: countOccurrences(productionManifest, "mountPath: /root/.agents/skills"),
|
||||
});
|
||||
@@ -81,6 +85,9 @@ assertCondition(countOccurrences(productionManifest, "name: skills-dir") >= 6, "
|
||||
count: countOccurrences(productionManifest, "name: skills-dir"),
|
||||
});
|
||||
assertCondition(devManifest.includes("path: /home/ubuntu/.agents/skills"), "dev manifest should keep the same hostPath source of truth");
|
||||
assertCondition(countOccurrences(devManifest, "name: CODE_QUEUE_RUNNER_SKILLS_SOURCE_PATH") === 3, "dev read/write/scheduler must expose the approved runner skills source path", {
|
||||
count: countOccurrences(devManifest, "name: CODE_QUEUE_RUNNER_SKILLS_SOURCE_PATH"),
|
||||
});
|
||||
|
||||
const devCodeQueueDeploy = (deployJson.environments?.dev?.services ?? []).find((service) => service.id === "code-queue");
|
||||
assertCondition(devCodeQueueDeploy !== undefined, "deploy.json dev environment must include code-queue");
|
||||
@@ -107,6 +114,71 @@ assertCondition(pinnedRuntimePreflight.includes("skills.contractOk && ports.code
|
||||
assertCondition(pinnedIndexSource.includes("skills.contractOk === true"), "deploy.json dev code-queue commit dev-ready must require target projection contract");
|
||||
assertCondition(pinnedIndexSource.includes("return config.skillsPath"), "deploy.json dev code-queue commit must keep runner UNIDESK_SKILLS_PATH on the configured target");
|
||||
|
||||
configureProviderRuntime({
|
||||
config: {
|
||||
codexHome: "/var/lib/unidesk/code-queue/codex-home",
|
||||
defaultWorkdir: "/workspace",
|
||||
devContainerDefaultProviderId: "D601",
|
||||
devContainerImage: "unidesk-code-queue:d601",
|
||||
devContainerMasterHost: "74.48.78.17",
|
||||
devContainerWorkdir: "/home/ubuntu",
|
||||
executionProviderIds: ["D601"],
|
||||
mainProviderId: "D601-main",
|
||||
remoteCodexEnvKeys: [],
|
||||
remoteDefaultWorkdir: "/home/ubuntu",
|
||||
runnerSkillsSourcePath: "/home/ubuntu/.agents/skills",
|
||||
skillsPath: "/root/.agents/skills",
|
||||
sourceCodexConfig: "/root/.codex/config.toml",
|
||||
windowsNativeCodexBridgeDir: "/home/ubuntu/.unidesk/code-queue/windows-native-codex",
|
||||
windowsNativeCodexCommand: "codex app-server --listen stdio://",
|
||||
windowsNativeCodexConnectHost: "host.docker.internal",
|
||||
windowsNativeCodexDefaultWorkdir: "/mnt/f/Work/ConStart",
|
||||
windowsNativeCodexIdleTimeoutMs: 600_000,
|
||||
},
|
||||
safePreview: (value: string, max = 1000) => value.slice(0, max),
|
||||
});
|
||||
const devContainerPlan = buildDevContainerPlan("D601", { workdir: "/home/ubuntu" });
|
||||
const devContainerStartScript = providerRuntimeForTest.remoteContainerStartScript(devContainerPlan, false);
|
||||
assertCondition(devContainerStartScript.includes("SKILLS_SOURCE='/home/ubuntu/.agents/skills'"), "provider dev container start must use the D601 host skills source", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes("SKILLS_TARGET='/root/.agents/skills'"), "provider dev container start must use the runner target skills path", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes('-v "$SKILLS_SOURCE":"$SKILLS_TARGET":ro'), "provider dev container must bind source skills read-only to target", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes('-e UNIDESK_SKILLS_PATH="$SKILLS_TARGET"'), "provider dev container must export UNIDESK_SKILLS_PATH in docker run", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes('test -r "$UNIDESK_SKILLS_PATH/docs-spec/SKILL.md"'), "provider dev container readiness must verify required docs-spec skill at target", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes('test -r "$UNIDESK_SKILLS_PATH/cli-spec/SKILL.md"'), "provider dev container readiness must verify required cli-spec skill at target", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes('test -r "$UNIDESK_SKILLS_PATH/frontend-design/SKILL.md"'), "provider dev container readiness must verify required frontend-design skill at target", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes("playwright-cli/SKILL.md") && devContainerStartScript.includes("playwright/SKILL.md"), "provider dev container readiness must accept the playwright-cli alias", devContainerStartScript);
|
||||
assertCondition(devContainerStartScript.includes("reuse_ready") && devContainerStartScript.includes('test "$UNIDESK_SKILLS_PATH" = "/root/.agents/skills"'), "provider dev container reuse must revalidate target skills before keeping an old container", devContainerStartScript);
|
||||
const remoteCodexCommand = providerRuntimeForTest.remoteAppServerCommand({
|
||||
id: "task",
|
||||
queueId: "default",
|
||||
prompt: "",
|
||||
status: "running",
|
||||
cwd: "/home/ubuntu",
|
||||
providerId: "D601",
|
||||
model: "gpt-5.5",
|
||||
executionMode: "default",
|
||||
currentAttempt: 1,
|
||||
attempts: 1,
|
||||
maxAttempts: 1,
|
||||
codexThreadId: null,
|
||||
reasoningEffort: null,
|
||||
createdAt: "2026-05-24T00:00:00.000Z",
|
||||
updatedAt: "2026-05-24T00:00:00.000Z",
|
||||
startedAt: "2026-05-24T00:00:00.000Z",
|
||||
completedAt: null,
|
||||
lastActivityAt: "2026-05-24T00:00:00.000Z",
|
||||
branch: null,
|
||||
commitSha: null,
|
||||
title: null,
|
||||
error: null,
|
||||
judge: null,
|
||||
outputSeq: 0,
|
||||
outputs: [],
|
||||
events: [],
|
||||
metadata: {},
|
||||
} as never);
|
||||
assertCondition(remoteCodexCommand.includes("export UNIDESK_SKILLS_PATH=") && remoteCodexCommand.includes("/root/.agents/skills"), "remote codex app-server must receive the target skills env", remoteCodexCommand);
|
||||
|
||||
const available = collectSkillAvailability({
|
||||
source: "/home/ubuntu/.agents/skills",
|
||||
target: "/home/ubuntu/.agents/skills",
|
||||
@@ -446,6 +518,7 @@ process.stdout.write(`${JSON.stringify({
|
||||
ok: true,
|
||||
checks: [
|
||||
"production Code Queue mounts /home/ubuntu/.agents/skills read-only at /root/.agents/skills",
|
||||
"provider dev containers bind /home/ubuntu/.agents/skills read-only at /root/.agents/skills and pass UNIDESK_SKILLS_PATH to Codex/OpenCode",
|
||||
"deploy.json dev Code Queue pins a commit whose manifest and runtime require the target skills projection",
|
||||
"skill availability report exposes source, target, requiredSkills, missingSkills, version fingerprint/mtime, degraded/blocker and valuesPrinted=false",
|
||||
"skills sync dry-run reports source, target, counts, version fingerprint/mtime, missing skills, permission failures, instructions and no-copy actions",
|
||||
|
||||
Reference in New Issue
Block a user