diff --git a/scripts/g14-ci-plan.test.mjs b/scripts/g14-ci-plan.test.mjs index 3eb172e8..5c3bd553 100644 --- a/scripts/g14-ci-plan.test.mjs +++ b/scripts/g14-ci-plan.test.mjs @@ -161,6 +161,8 @@ test("component model uses built-in service paths", () => { "cmd/hwlab-cloud-api/", "cmd/hwlab-codex-api-responses-forwarder/", "cmd/hwlab-deepseek-responses-bridge/", + "internal/agent/agentrun-dispatch.mjs", + "internal/agent/prompts/", "internal/audit/", "internal/cloud/", "internal/db/", @@ -169,6 +171,58 @@ test("component model uses built-in service paths", () => { assert.deepEqual(matchingPaths(["cmd/hwlab-cloud-api/main.ts"], models[0].componentPaths), ["cmd/hwlab-cloud-api/main.ts"]); }); +test("v02 planner treats AgentRun runtime prompt changes as cloud-api inputs", async () => { + const repo = await createFixtureRepo({ includeDevicePod: true }); + await mkdir(path.join(repo, "internal/agent/prompts"), { recursive: true }); + await writeFile(path.join(repo, "internal/agent/agentrun-dispatch.mjs"), "export const prompt = true;\n"); + await writeFile(path.join(repo, "internal/agent/prompts/hwlab-v02-runtime.md"), "prompt v1\n"); + await git(repo, ["add", "."]); + await git(repo, ["commit", "-m", "seed agentrun prompt"]); + const initialSha = (await git(repo, ["rev-parse", "HEAD"])).stdout.trim(); + const initialPlan = await createG14CiPlan({ + repoRoot: repo, + lane: "v02", + baseRef: "HEAD", + targetRef: initialSha, + artifactCatalogPath: "deploy/artifact-catalog.v02.json", + services: ["hwlab-cloud-api", "hwlab-cloud-web", "hwlab-device-pod"] + }); + const initialCloudWeb = initialPlan.services.find((service) => service.serviceId === "hwlab-cloud-web"); + const initialDevicePod = initialPlan.services.find((service) => service.serviceId === "hwlab-device-pod"); + const initialHashes = Object.fromEntries(initialPlan.services.map((service) => [service.serviceId, service.componentInputHash])); + await writeFile(path.join(repo, "deploy/artifact-catalog.v02.json"), JSON.stringify(createCatalogFixture("ready", { + sourceCommitId: initialPlan.sourceCommitId, + componentInputHashes: initialHashes, + cloudWebEnvironmentInputHash: initialCloudWeb.environmentInputHash, + cloudWebCodeInputHash: initialCloudWeb.codeInputHash, + cloudWebBootCommit: initialPlan.sourceCommitId, + devicePodEnvironmentInputHash: initialDevicePod.environmentInputHash, + devicePodCodeInputHash: initialDevicePod.codeInputHash, + devicePodBootCommit: initialPlan.sourceCommitId + }), null, 2)); + await git(repo, ["add", "deploy/artifact-catalog.v02.json"]); + await git(repo, ["commit", "-m", "seed v02 catalog with agentrun prompt"]); + + await writeFile(path.join(repo, "internal/agent/prompts/hwlab-v02-runtime.md"), "prompt v2\n"); + await git(repo, ["add", "internal/agent/prompts/hwlab-v02-runtime.md"]); + await git(repo, ["commit", "-m", "change agentrun prompt"]); + + const plan = await createG14CiPlan({ + repoRoot: repo, + lane: "v02", + baseRef: "HEAD~1", + targetRef: "HEAD", + artifactCatalogPath: "deploy/artifact-catalog.v02.json", + services: ["hwlab-cloud-api", "hwlab-cloud-web", "hwlab-device-pod"] + }); + assert.deepEqual(plan.affectedServices, ["hwlab-cloud-api"]); + assert.deepEqual(plan.buildServices, ["hwlab-cloud-api"]); + assert.deepEqual(plan.rolloutServices, ["hwlab-cloud-api"]); + const cloudApi = plan.services.find((service) => service.serviceId === "hwlab-cloud-api"); + assert.deepEqual(cloudApi.changedPaths, ["internal/agent/prompts/hwlab-v02-runtime.md"]); + assert.deepEqual(cloudApi.reason, ["component-path-changed"]); +}); + test("planner scopes cloud-web runtime changes to cloud-web", async () => { const repo = await createFixtureRepo(); await writeFile(path.join(repo, "internal/dev-entrypoint/cloud-web-runtime.mjs"), "export const runtime = 2;\n"); diff --git a/scripts/src/g14-ci-plan-lib.mjs b/scripts/src/g14-ci-plan-lib.mjs index 99389390..03c2f34a 100644 --- a/scripts/src/g14-ci-plan-lib.mjs +++ b/scripts/src/g14-ci-plan-lib.mjs @@ -71,6 +71,8 @@ const serviceSpecificPaths = Object.freeze({ "internal/cloud/", "internal/db/", "internal/audit/", + "internal/agent/agentrun-dispatch.mjs", + "internal/agent/prompts/", "skills/hwlab-agent-runtime/" ], "hwlab-cloud-web": [ @@ -438,6 +440,8 @@ export function isTestOnlyPath(filePath) { export function isDocsOnlyPath(filePath) { const normalized = normalizeRepoPath(filePath); + if (normalized.startsWith("internal/agent/prompts/")) return false; + if (normalized.startsWith("skills/")) return false; return DEFAULT_DOCS_ONLY_PATHS.some((pattern) => pathMatches(pattern, normalized)) || normalized.endsWith(".md"); }