From dc9c11be917ebdc711b956250aa80a8e5b47bea6 Mon Sep 17 00:00:00 2001 From: Vincent Koc Date: Tue, 23 Jun 2026 17:37:42 +0200 Subject: [PATCH] fix(qa): reject duplicate plugin gauntlet controls --- scripts/check-plugin-gateway-gauntlet.mjs | 25 ++++++++++++++++++++ test/scripts/plugin-gateway-gauntlet.test.ts | 9 +++++++ 2 files changed, 34 insertions(+) diff --git a/scripts/check-plugin-gateway-gauntlet.mjs b/scripts/check-plugin-gateway-gauntlet.mjs index 62da98d4a4d7..984a0f6e17cb 100644 --- a/scripts/check-plugin-gateway-gauntlet.mjs +++ b/scripts/check-plugin-gateway-gauntlet.mjs @@ -35,6 +35,24 @@ const DEFAULT_CPU_CORE_WARN = 0.9; const DEFAULT_HOT_WALL_WARN_MS = 30_000; const DEFAULT_MAX_RSS_WARN_MB = 1536; const DEFAULT_QA_PLUGIN_CHUNK_SIZE = 12; +const SINGLE_VALUE_FLAGS = new Set([ + "--build-timeout-ms", + "--command-timeout-ms", + "--cpu-core-warn", + "--hot-wall-warn-ms", + "--limit", + "--max-rss-warn-mb", + "--output-dir", + "--qa-cpu-regression-multiplier", + "--qa-plugin-chunk-size", + "--qa-timeout-ms", + "--qa-wall-regression-multiplier", + "--repo-root", + "--rss-anomaly-multiplier", + "--shard-index", + "--shard-total", + "--wall-anomaly-multiplier", +]); const COMMAND_OUTPUT_MAX_BUFFER_BYTES = 16 * 1024 * 1024; const MAX_TIMER_TIMEOUT_MS = 2_147_000_000; const ANSI_PATTERN = new RegExp(String.raw`\u001B\[[0-9;]*m`, "gu"); @@ -79,8 +97,15 @@ export function parseArgs(argv) { }; const envIds = normalizeCsv(process.env.OPENCLAW_PLUGIN_GATEWAY_GAUNTLET_IDS); options.pluginIds.push(...envIds); + const seenSingleValueFlags = new Set(); parseArgv: for (let index = 0; index < args.length; index += 1) { const arg = args[index]; + if (SINGLE_VALUE_FLAGS.has(arg)) { + if (seenSingleValueFlags.has(arg)) { + throw new Error(`${arg} was provided more than once`); + } + seenSingleValueFlags.add(arg); + } const readValue = () => { const value = args[index + 1]; if (!value || value.startsWith("-")) { diff --git a/test/scripts/plugin-gateway-gauntlet.test.ts b/test/scripts/plugin-gateway-gauntlet.test.ts index 9859d5ea56eb..1396da81dcae 100644 --- a/test/scripts/plugin-gateway-gauntlet.test.ts +++ b/test/scripts/plugin-gateway-gauntlet.test.ts @@ -150,6 +150,15 @@ describe("plugin gateway gauntlet helpers", () => { ); }); + it("rejects duplicate single-value controls", () => { + expect(() => + parseArgs(["--output-dir", ".artifacts/one", "--output-dir", ".artifacts/two"]), + ).toThrow("--output-dir was provided more than once"); + expect(() => parseArgs(["--shard-total", "2", "--shard-total", "3"])).toThrow( + "--shard-total was provided more than once", + ); + }); + it("rejects valued flags followed by another option", () => { for (const flag of [ "--repo-root",