Skip to content

Commit 94f9f26

Browse files
committed
fix: fail closed on unapplied fault schedules
1 parent 3c9934a commit 94f9f26

2 files changed

Lines changed: 7 additions & 0 deletions

File tree

packages/cli/src/recipe-validation.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,9 @@ function validateRecipeAdversarialCampaigns(recipe: WorkspaceRecipe, recipePath:
11701170
}
11711171
const missing = (campaign.requiredCapabilities ?? []).filter((capability) => !available.has(capability))
11721172
if (missing.length > 0) throw new Error(`Recipe adversarial campaign ${campaign.id} requires unavailable capabilities: ${missing.join(", ")}: ${recipePath}`)
1173+
if (campaign.faultSchedule && !(campaign.requiredCapabilities ?? []).includes("transport-faults")) {
1174+
throw new Error(`Recipe adversarial campaign ${campaign.id} faultSchedule requires the transport-faults capability: ${recipePath}`)
1175+
}
11731176
if ((campaign.concurrency ?? 1) > 1 && !(campaign.requiredCapabilities ?? []).includes("isolated-workers")) {
11741177
throw new Error(`Recipe adversarial campaign ${campaign.id} concurrency above 1 requires isolated-workers capability: ${recipePath}`)
11751178
}

tests/adversarial-recipe-orchestration.test.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,10 @@ const unsupportedRecipe = structuredClone(recipe)
7979
unsupportedRecipe.adversarialCampaigns![0]!.requiredCapabilities = ["missing-adapter"]
8080
assert.throws(() => validateWorkspaceRecipeShape(unsupportedRecipe, "unsupported.json"), /requires unavailable capabilities: missing-adapter/)
8181

82+
const unsafeFaultRecipe = structuredClone(recipe)
83+
unsafeFaultRecipe.adversarialCampaigns![0]!.faultSchedule = { schema: "wp-codebox/transport-fault-model/v1", seed: "faults", rules: [] }
84+
assert.throws(() => validateWorkspaceRecipeShape(unsafeFaultRecipe, "faults.json"), /faultSchedule requires the transport-faults capability/)
85+
8286
const artifactRoot = await mkdtemp(join(tmpdir(), "wp-codebox-adversarial-recipe-"))
8387
try {
8488
const manifestPath = join(artifactRoot, "manifest.json")

0 commit comments

Comments
 (0)