import { readFileSync } from "node:fs"; import { collectSkillAvailability } from "../src/components/microservices/code-queue/src/skill-availability"; type JsonRecord = Record; function assertCondition(condition: unknown, message: string, detail: unknown = {}): void { if (!condition) throw new Error(`${message}: ${JSON.stringify(detail)}`); } function asRecord(value: unknown, label: string): JsonRecord { assertCondition(typeof value === "object" && value !== null && !Array.isArray(value), `${label} must be an object`, value); return value as JsonRecord; } function countOccurrences(haystack: string, needle: string): number { return haystack.split(needle).length - 1; } const productionManifest = readFileSync("src/components/microservices/k3sctl-adapter/k3s/code-queue.k8s.yaml", "utf8"); const devManifest = readFileSync("src/components/microservices/k3sctl-adapter/k3s/dev/unidesk-dev-code-queue.k8s.yaml", "utf8"); const runtimePreflight = readFileSync("src/components/microservices/code-queue/src/runtime-preflight.ts", "utf8"); const indexSource = readFileSync("src/components/microservices/code-queue/src/index.ts", "utf8"); const skillModule = readFileSync("src/components/microservices/code-queue/src/skill-availability.ts", "utf8"); const promptSource = readFileSync("src/components/microservices/code-queue/src/prompts.ts", "utf8"); const docsReference = readFileSync("docs/reference/code-queue-supervision.md", "utf8"); const forbiddenPathLiteral = [".ag", "nets/skills"].join(""); assertCondition(!productionManifest.includes(forbiddenPathLiteral), "production manifest must not propagate misspelled skills path"); assertCondition(!devManifest.includes(forbiddenPathLiteral), "dev manifest must not propagate misspelled skills path"); assertCondition(!promptSource.includes(forbiddenPathLiteral), "runner prompt must not mention misspelled skills path"); assertCondition(!skillModule.includes(forbiddenPathLiteral), "skill availability implementation must not propagate misspelled skills path literal"); assertCondition(!docsReference.includes(forbiddenPathLiteral), "reference docs must not propagate misspelled skills path literal"); 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, "mountPath: /root/.agents/skills") === 3, "production read/write/scheduler must mount skills target", { count: countOccurrences(productionManifest, "mountPath: /root/.agents/skills"), }); assertCondition(countOccurrences(productionManifest, "path: /home/ubuntu/.agents/skills") === 3, "production read/write/scheduler must use hostPath source of truth", { count: countOccurrences(productionManifest, "path: /home/ubuntu/.agents/skills"), }); assertCondition(countOccurrences(productionManifest, "name: skills-dir") >= 6, "production manifest must define skills-dir mounts and volumes", { count: countOccurrences(productionManifest, "name: skills-dir"), }); assertCondition(devManifest.includes("path: /home/ubuntu/.agents/skills"), "dev manifest should keep the same hostPath source of truth"); const available = collectSkillAvailability({ source: "/home/ubuntu/.agents/skills", target: "/home/ubuntu/.agents/skills", requiredSkills: ["docs-spec", "cli-spec", "frontend-design", "playwright-cli"], }); assertCondition(available.source === "/home/ubuntu/.agents/skills", "skill report must expose source"); assertCondition(available.target === "/home/ubuntu/.agents/skills", "skill report must expose target"); assertCondition(Array.isArray(available.requiredSkills) && available.requiredSkills.includes("docs-spec"), "skill report must expose requiredSkills"); assertCondition(Array.isArray(available.missingSkills), "skill report must expose missingSkills"); assertCondition(available.valuesPrinted === false, "skill report must declare valuesPrinted=false"); assertCondition(asRecord(available.pathSpelling, "pathSpelling").forbiddenPathMustNotBeUsed === true, "skill report must flag misspelled path risk without spreading the literal path"); assertCondition(!JSON.stringify(available).includes(forbiddenPathLiteral), "skill report must not propagate misspelled path literal"); assertCondition(!JSON.stringify(available).includes("GH_TOKEN"), "skill report must not include secret environment names unrelated to skills"); const missing = collectSkillAvailability({ source: "/home/ubuntu/.agents/skills", target: "/path/that/does/not/exist/for-code-queue-skills-test", requiredSkills: ["docs-spec", "cli-spec"], }); assertCondition(missing.ok === false, "missing target should fail"); assertCondition(missing.degraded === true, "missing target should be degraded"); assertCondition(missing.blocker === "skills-target-missing", "missing target should expose blocker", missing); assertCondition(missing.missingSkills.includes("docs-spec") && missing.missingSkills.includes("cli-spec"), "missing target should list required missing skills", missing); assertCondition(missing.valuesPrinted === false, "missing report must also declare valuesPrinted=false"); assertCondition(runtimePreflight.includes("skills: SkillAvailabilityReport"), "runtime preflight type must include skills report"); assertCondition(runtimePreflight.includes("collectSkillAvailability"), "runtime preflight must collect skills availability"); assertCondition(runtimePreflight.includes("skills.ok && ports.codex.ok"), "runtime preflight ok must depend on skills.ok"); assertCondition(indexSource.includes("const skillsReady = skills.ok === true"), "dev-ready must gate on structured skills ok"); process.stdout.write(`${JSON.stringify({ ok: true, checks: [ "production Code Queue mounts /home/ubuntu/.agents/skills read-only at /root/.agents/skills", "skill availability report exposes source, target, requiredSkills, missingSkills, degraded/blocker and valuesPrinted=false", "runtime-preflight and dev-ready use the same structured skill report", "misspelled skills paths are only surfaced as a forbidden diagnostic risk", ], observedRunner: { source: available.source, target: available.target, ok: available.ok, missingSkills: available.missingSkills, valuesPrinted: available.valuesPrinted, }, }, null, 2)}\n`);