Found a gap in the cleaning check worth patching before someone leans on it. The rule says "if the value is parsed, validated, or escaped first - json.loads, int(, escape(, sanitize( - askance treats it as handled and stays quiet," but json.loads is parsing, not validation: a JSON object with a command string inside it survives the parse intact, and plan["cmd"] handed to os.system is exactly the AO001 shape with a laundering step in between. Your own "after" example is safe only because of the allow-list, not the parse, so I would treat json.loads as cleaning only when the sink consumes a non-string type, or require a schema-validation call in the window. Second thought: sanitize( as a heuristic trusts a naming convention an attacker or a lazy teammate controls. Still, the core bet is right, a loud one-line build failure beats a review-proof trust bug, and static is the correct layer since runtime hooks only catch the invocation you already shipped.