원클릭으로
new-mutator
Scaffold a new AST mutator class with tests and register it in the engine
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Scaffold a new AST mutator class with tests and register it in the engine
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
| name | new-mutator |
| description | Scaffold a new AST mutator class with tests and register it in the engine |
| argument-hint | <MutatorName> [scenario-module] |
| disable-model-invocation | true |
| user-invocable | true |
Create a new AST mutator named $ARGUMENTS.
Pick the correct scenario module based on the mutator's purpose:
| Module | Purpose |
|---|---|
lafleur/mutators/generic.py | General-purpose structural mutations (operator swap, constant perturbation, loop injection) |
lafleur/mutators/scenarios_types.py | Type system and caching attacks (type instability, inline cache, MRO) |
lafleur/mutators/scenarios_control.py | Control flow stress testing (deep calls, recursion, exception mazes, coroutines) |
lafleur/mutators/scenarios_data.py | Data structure manipulation (dict pollution, comprehension bombs, magic methods) |
lafleur/mutators/scenarios_runtime.py | Runtime state corruption (frame manipulation, GC stress, eval frame hooks) |
If the user specified a module as the second argument, use that. Otherwise, infer from the mutator name and purpose.
Read the chosen module first to understand existing patterns. Then add the new class following one of these patterns:
class MyMutator(ast.NodeTransformer):
"""One-line description of what this mutator does."""
def visit_FunctionDef(self, node: ast.FunctionDef) -> ast.FunctionDef:
if not node.name.startswith("uop_harness"):
return node
if random.random() < 0.1: # Probabilistic application
scenario = ast.parse(textwrap.dedent("""\
# injected code here
""")).body
node.body = scenario + node.body
ast.fix_missing_locations(node)
return node
class MyMutator(ast.NodeTransformer):
"""One-line description of what this mutator does."""
def visit_BinOp(self, node: ast.BinOp) -> ast.BinOp:
if random.random() < 0.3:
node.op = ast.Sub()
return node
ast.NodeTransformerrandom.random() < threshold (typically 0.05-0.15)visit_FunctionDef: check node.name.startswith("uop_harness") and skip non-harness functionsast.fix_missing_locations(node) after modifying node bodiestextwrap.dedent() for multi-line injected codelafleur/mutators/engine.py in the appropriate import block (sorted alphabetically within the block for the source module)self.transformers list in ASTMutator.__init__(), placed near related mutatorsAdd an entry under ## [0.1.x] - Unreleased → ### Added describing what the mutator does and what JIT weakness it targets. Follow the existing format:
- A `MyMutator` that <what it does> to <JIT weakness targeted>, by @devdanzin.
Add tests to the matching test file under tests/mutators/:
| Source module | Test file |
|---|---|
generic.py | tests/mutators/test_generic.py |
scenarios_types.py | tests/mutators/test_scenarios_types.py |
scenarios_control.py | tests/mutators/test_scenarios_control.py |
scenarios_data.py | tests/mutators/test_scenarios_data.py |
scenarios_runtime.py | tests/mutators/test_scenarios_runtime.py |
Read the target test file first to follow the existing test class pattern. Every mutator test class needs:
random.random patched low (e.g. 0.05), verify the AST is modifiedrandom.random to return 0.99, verify no mutation appliedast.unparse(mutated_tree) succeeds and compile() succeedsuop_harness* are left unchangedclass TestMyMutator(unittest.TestCase):
def test_basic_mutation(self):
code = textwrap.dedent("""\
def uop_harness_test():
x = 1
y = x + 2
""")
tree = ast.parse(code)
with patch("random.random", return_value=0.05):
mutated = MyMutator().visit(tree)
result = ast.unparse(mutated)
# Assert mutation was applied...
def test_skipped_at_high_probability(self):
code = textwrap.dedent("""\
def uop_harness_test():
x = 1
""")
tree = ast.parse(code)
original = ast.dump(tree)
with patch("random.random", return_value=0.99):
mutated = MyMutator().visit(tree)
self.assertEqual(ast.dump(mutated), original)
Run these commands:
ruff format lafleur/mutators/<module>.py tests/mutators/<test_file>.py lafleur/mutators/engine.py
ruff check lafleur/mutators/<module>.py tests/mutators/<test_file>.py lafleur/mutators/engine.py
~/venvs/jit_cpython_venv/bin/python -m pytest tests/mutators/<test_file>.py -v -k TestMyMutator
~/venvs/jit_cpython_venv/bin/python -m pytest tests/ -v