diff --git a/.specgit.yaml b/.specgit.yaml index 9c8ce01..33ca5e5 100644 --- a/.specgit.yaml +++ b/.specgit.yaml @@ -1,8 +1,11 @@ version: 1 -delivery: specgit-harness +delivery: release-route-worker context: kind: branch - branch: chore/17-specgit-harness + branch: fix/22-release-route-worker issues: - - 17 -pr: 21 + - 22 +issueKinds: + - issue: 22 + kind: kind::fix +pr: 23 diff --git a/release-route.yaml b/release-route.yaml index aaea6bc..73c8a2a 100644 --- a/release-route.yaml +++ b/release-route.yaml @@ -75,7 +75,7 @@ config: - id: release-verify name: "verify the release landed" - worker_type: verify + worker_type: general depends_on: [release-execute] prompt_template: inline: >- diff --git a/script/validate-route-catalog.test.ts b/script/validate-route-catalog.test.ts index 24d1dbd..f366660 100644 --- a/script/validate-route-catalog.test.ts +++ b/script/validate-route-catalog.test.ts @@ -98,6 +98,20 @@ describe("route catalog guardrails", () => { expect(result.exitCode).toBe(1) expect(result.stderr).toContain("Route catalog must contain exactly") }) + + test("rejects a worker_type outside the compatible runtime agent catalog", async () => { + await rewrite( + "release-route.yaml", + 'name: "verify the release landed"\n worker_type: general', + 'name: "verify the release landed"\n worker_type: verify', + ) + + const result = await validate() + expect(result.exitCode).toBe(1) + expect(result.stderr).toContain( + "not in the compatible runtime agent catalog", + ) + }) }) async function rewrite(file: string, before: string, after: string) { diff --git a/script/validate-route-catalog.ts b/script/validate-route-catalog.ts index 4ad5f44..70ccbd0 100644 --- a/script/validate-route-catalog.ts +++ b/script/validate-route-catalog.ts @@ -20,6 +20,11 @@ const expected = domains const crossDomainRoutes = ["release-route.yaml", "ultra-flow-route.yaml"] const catalog = [...expected, ...crossDomainRoutes].sort() const routeNames = catalog.map((file) => path.basename(file, ".yaml")) +// The compatible runtime gate (runtime-compat.json, commit b48dce46) rejects +// any node whose worker_type is outside its builtin agent catalog +// (build, plan, general, explore); the portable profile skips the catalog when +// absent, so this check closes the gap config-side. +const compatibleWorkerTypes = ["explore", "build", "plan", "general"] const files = (await fs.readdir(root)) // Hidden dotfiles are delivery tooling (e.g. the SpecGit `.specgit.yaml` // binding), never route templates; the catalog inventory is over visible files. @@ -43,6 +48,25 @@ for (const filename of catalog) { if (parsed.config.name !== name) fail(`${filename} config.name must equal ${name}`) if (name.endsWith("-lite")) validateLiteRoute(filename, parsed.config) + validateWorkerTypes(filename, parsed.config) +} + +function validateWorkerTypes( + filename: string, + config: Record, +) { + const workers = [ + ...(Array.isArray(config.nodes) ? config.nodes : []), + ...(Array.isArray(config.blocks) ? config.blocks : []), + ].filter(isRecord) + for (const worker of workers) { + if (worker.worker_type === undefined) continue + const workerType = String(worker.worker_type) + if (compatibleWorkerTypes.includes(workerType)) continue + fail( + `${filename} node ${worker.id} worker type "${workerType}" is not in the compatible runtime agent catalog (${compatibleWorkerTypes.join(", ")})`, + ) + } } console.log(