evilution 0.29.0 → 0.30.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.beads/interactions.jsonl +54 -0
  3. data/.rubocop_todo.yml +7 -0
  4. data/CHANGELOG.md +42 -0
  5. data/README.md +194 -8
  6. data/docs/versioning.md +53 -0
  7. data/lib/evilution/ast/heredoc_span.rb +99 -0
  8. data/lib/evilution/baseline.rb +15 -2
  9. data/lib/evilution/cli/commands/compare.rb +13 -0
  10. data/lib/evilution/cli/parser/command_extractor.rb +3 -1
  11. data/lib/evilution/cli/parser/options_builder.rb +2 -2
  12. data/lib/evilution/config/file_loader.rb +40 -1
  13. data/lib/evilution/config.rb +11 -1
  14. data/lib/evilution/equivalent/heuristic/dead_code.rb +8 -1
  15. data/lib/evilution/feedback/setup_warning.rb +79 -0
  16. data/lib/evilution/gem_detector.rb +132 -0
  17. data/lib/evilution/integration/loading/body_call_neutralizer.rb +190 -0
  18. data/lib/evilution/integration/loading/mutation_applier.rb +20 -5
  19. data/lib/evilution/integration/loading/redefinition_recovery.rb +58 -1
  20. data/lib/evilution/integration/minitest.rb +37 -2
  21. data/lib/evilution/integration/rspec/result_builder.rb +20 -1
  22. data/lib/evilution/integration/rspec.rb +16 -1
  23. data/lib/evilution/isolation/fork.rb +77 -10
  24. data/lib/evilution/mcp/info_tool/response_formatter.rb +14 -1
  25. data/lib/evilution/mcp/info_tool.rb +3 -1
  26. data/lib/evilution/mcp/mutate_tool/option_parser.rb +1 -1
  27. data/lib/evilution/mcp/mutate_tool/report_trimmer.rb +58 -1
  28. data/lib/evilution/mcp/mutate_tool.rb +22 -3
  29. data/lib/evilution/mcp/session_tool.rb +7 -4
  30. data/lib/evilution/mcp.rb +6 -0
  31. data/lib/evilution/mutation.rb +13 -1
  32. data/lib/evilution/mutator/base.rb +49 -1
  33. data/lib/evilution/mutator/operator/argument_method_call_replacement.rb +59 -0
  34. data/lib/evilution/mutator/operator/block_param_removal.rb +32 -0
  35. data/lib/evilution/mutator/operator/explicit_super_mutation.rb +20 -2
  36. data/lib/evilution/mutator/operator/index_to_at.rb +13 -1
  37. data/lib/evilution/mutator/operator/last_expression_removal.rb +46 -0
  38. data/lib/evilution/mutator/operator/receiver_replacement.rb +29 -1
  39. data/lib/evilution/mutator/operator/rescue_removal.rb +59 -10
  40. data/lib/evilution/mutator/operator/splat_operator.rb +28 -1
  41. data/lib/evilution/mutator/operator/string_literal.rb +83 -6
  42. data/lib/evilution/mutator/registry.rb +2 -0
  43. data/lib/evilution/reporter/cli/line_formatters/error_rate_warning.rb +29 -0
  44. data/lib/evilution/reporter/cli/metrics_block.rb +2 -0
  45. data/lib/evilution/reporter/json.rb +2 -0
  46. data/lib/evilution/result/mutation_result.rb +12 -6
  47. data/lib/evilution/runner/baseline_runner.rb +5 -1
  48. data/lib/evilution/runner/isolation_resolver.rb +69 -8
  49. data/lib/evilution/runner/mutation_planner.rb +18 -1
  50. data/lib/evilution/session/schema.rb +44 -0
  51. data/lib/evilution/session/store.rb +5 -1
  52. data/lib/evilution/version.rb +1 -1
  53. data/lib/evilution.rb +2 -0
  54. data/schema/evilution.config.schema.json +205 -0
  55. data/script/build_runtime_snapshot +88 -0
  56. data/script/run_self_baseline +79 -0
  57. data/script/run_self_validation +54 -0
  58. metadata +15 -2
@@ -0,0 +1,205 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://github.com/marinazzio/evilution/blob/master/schema/evilution.config.schema.json",
4
+ "title": "Evilution Configuration",
5
+ "description": "Schema for .evilution.yml / config/evilution.yml. Declaring `schema_version` opts the file into strict validation at load time.",
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "properties": {
9
+ "schema_version": {
10
+ "type": "integer",
11
+ "enum": [1],
12
+ "description": "Config schema version. Currently must be 1. Declaring it enables strict validation: unknown keys are rejected and a future schema_version is refused."
13
+ },
14
+ "timeout": {
15
+ "type": "integer",
16
+ "minimum": 1,
17
+ "default": 30,
18
+ "description": "Per-mutation timeout in seconds."
19
+ },
20
+ "format": {
21
+ "type": "string",
22
+ "enum": ["text", "json", "html"],
23
+ "default": "text",
24
+ "description": "Output format."
25
+ },
26
+ "target": {
27
+ "type": ["string", "null"],
28
+ "default": null,
29
+ "description": "Filter expression: method (Foo#bar), class (Foo), namespace wildcard (Foo*), method-type selector (Foo# / Foo.), descendants (descendants:Foo), or source glob (source:**/*.rb)."
30
+ },
31
+ "min_score": {
32
+ "type": "number",
33
+ "minimum": 0.0,
34
+ "maximum": 1.0,
35
+ "default": 0.0,
36
+ "description": "Minimum mutation score (0.0–1.0) for exit code 0."
37
+ },
38
+ "integration": {
39
+ "type": "string",
40
+ "enum": ["rspec", "minitest"],
41
+ "default": "rspec",
42
+ "description": "Test framework integration."
43
+ },
44
+ "verbose": {
45
+ "type": "boolean",
46
+ "default": false,
47
+ "description": "Verbose output (RSS/GC stats per phase, error details for errored mutations)."
48
+ },
49
+ "quiet": {
50
+ "type": "boolean",
51
+ "default": false,
52
+ "description": "Suppress output."
53
+ },
54
+ "jobs": {
55
+ "type": "integer",
56
+ "minimum": 1,
57
+ "default": 1,
58
+ "description": "Number of parallel workers."
59
+ },
60
+ "fail_fast": {
61
+ "type": ["integer", "null"],
62
+ "minimum": 1,
63
+ "default": null,
64
+ "description": "Stop after N surviving mutants. null or omitted = disabled."
65
+ },
66
+ "baseline": {
67
+ "type": "boolean",
68
+ "default": true,
69
+ "description": "Run baseline test suite first to detect pre-existing failures and mark those mutations :neutral."
70
+ },
71
+ "isolation": {
72
+ "type": "string",
73
+ "enum": ["auto", "fork", "in_process"],
74
+ "default": "auto",
75
+ "description": "Isolation strategy. auto selects fork for Rails projects."
76
+ },
77
+ "incremental": {
78
+ "type": "boolean",
79
+ "default": false,
80
+ "description": "Cache killed/timeout results across runs and skip them when source is unchanged."
81
+ },
82
+ "suggest_tests": {
83
+ "type": "boolean",
84
+ "default": false,
85
+ "description": "Generate concrete test code in survivor suggestions (RSpec or Minitest, matching integration)."
86
+ },
87
+ "progress": {
88
+ "type": "boolean",
89
+ "default": true,
90
+ "description": "TTY progress bar."
91
+ },
92
+ "save_session": {
93
+ "type": "boolean",
94
+ "default": false,
95
+ "description": "Save session JSON under .evilution/results/."
96
+ },
97
+ "line_ranges": {
98
+ "type": "object",
99
+ "default": {},
100
+ "description": "Per-file line-range constraints. Typically set via CLI; rare in YAML.",
101
+ "additionalProperties": true
102
+ },
103
+ "spec_files": {
104
+ "type": "array",
105
+ "items": { "type": "string" },
106
+ "default": [],
107
+ "description": "Explicit spec files to run. Bypasses auto-detection when non-empty."
108
+ },
109
+ "ignore_patterns": {
110
+ "type": "array",
111
+ "items": { "type": "string" },
112
+ "default": [],
113
+ "description": "AST patterns to skip during mutation generation. See docs/ast_pattern_syntax.md."
114
+ },
115
+ "show_disabled": {
116
+ "type": "boolean",
117
+ "default": false,
118
+ "description": "Report mutations skipped by `# evilution:disable` comments."
119
+ },
120
+ "baseline_session": {
121
+ "type": ["string", "null"],
122
+ "default": null,
123
+ "description": "Saved session file path for HTML report comparison."
124
+ },
125
+ "skip_heredoc_literals": {
126
+ "type": "boolean",
127
+ "default": false,
128
+ "description": "Skip all string literal mutations inside heredocs (recommended for Rails: heredoc SQL/templates rarely have coverage)."
129
+ },
130
+ "related_specs_heuristic": {
131
+ "type": "boolean",
132
+ "default": false,
133
+ "description": "When a mutation removes an `includes(...)` call, also run matching specs from spec/{requests,integration,features,system}."
134
+ },
135
+ "fallback_to_full_suite": {
136
+ "type": "boolean",
137
+ "default": false,
138
+ "description": "When no matching spec resolves, run the entire suite instead of marking the mutation :unresolved."
139
+ },
140
+ "preload": {
141
+ "type": ["string", "boolean", "null"],
142
+ "default": null,
143
+ "description": "Path to preload before forking workers. false to disable. null to auto-detect spec/rails_helper.rb -> spec/spec_helper.rb -> test/test_helper.rb for Rails projects."
144
+ },
145
+ "spec_mappings": {
146
+ "type": "object",
147
+ "default": {},
148
+ "description": "Custom mapping from source file to spec file(s). Keys are source paths; values are spec path strings or arrays of spec paths.",
149
+ "additionalProperties": {
150
+ "oneOf": [
151
+ { "type": "string" },
152
+ { "type": "array", "items": { "type": "string" } }
153
+ ]
154
+ }
155
+ },
156
+ "spec_pattern": {
157
+ "type": ["string", "null"],
158
+ "default": null,
159
+ "description": "Glob restricting resolved spec candidates to files matching this pattern."
160
+ },
161
+ "example_targeting": {
162
+ "type": "boolean",
163
+ "default": true,
164
+ "description": "Per-mutation example-level targeting via body-token scan."
165
+ },
166
+ "example_targeting_fallback": {
167
+ "type": "string",
168
+ "enum": ["full_file", "unresolved"],
169
+ "default": "full_file",
170
+ "description": "Behavior when targeting finds no matching example."
171
+ },
172
+ "example_targeting_cache": {
173
+ "type": "object",
174
+ "default": { "max_files": 50, "max_blocks": 10000 },
175
+ "additionalProperties": false,
176
+ "description": "LRU cache bounds for the spec AST parser that powers example targeting.",
177
+ "properties": {
178
+ "max_files": { "type": "integer", "minimum": 1 },
179
+ "max_blocks": { "type": "integer", "minimum": 1 }
180
+ }
181
+ },
182
+ "quiet_children": {
183
+ "type": "boolean",
184
+ "default": false,
185
+ "description": "Redirect each worker's stdout/stderr to per-pid files under quiet_children_dir."
186
+ },
187
+ "quiet_children_dir": {
188
+ "type": "string",
189
+ "default": "tmp/evilution_children",
190
+ "description": "Directory for --quiet-children per-pid log files."
191
+ },
192
+ "profile": {
193
+ "type": "string",
194
+ "enum": ["default", "strict"],
195
+ "default": "default",
196
+ "description": "Operator profile. strict adds aggressive truthiness mutators on top of default."
197
+ },
198
+ "hooks": {
199
+ "type": "object",
200
+ "default": {},
201
+ "additionalProperties": { "type": "string" },
202
+ "description": "Lifecycle hooks: keys are event names (e.g. worker_process_start, mutation_insert_pre); values are paths to Ruby files returning a Proc."
203
+ }
204
+ }
205
+ }
@@ -0,0 +1,88 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Builds tmp/evilution-runtime/ — a renamed copy of lib/ + exe/ where the
5
+ # Evilution module is rebranded to EvilutionRuntime. Used by bin/evilution-self
6
+ # so the mutation harness stays out of the namespace that subject `eval` clobbers.
7
+ # Throwaway dogfood infrastructure (EV-yyd8). No tests.
8
+
9
+ require "fileutils"
10
+
11
+ ROOT = File.expand_path("..", __dir__)
12
+ SNAPSHOT = File.join(ROOT, "tmp", "evilution-runtime")
13
+ SUBJECT_LIB = File.join(ROOT, "lib")
14
+ SUBJECT_EXE = File.join(ROOT, "exe")
15
+
16
+ def main
17
+ prepare_destination
18
+ copy_sources
19
+ rename_entrypoints
20
+ rewrite_sources
21
+ write_snapshot_sha
22
+ print_summary
23
+ end
24
+
25
+ def prepare_destination
26
+ FileUtils.rm_rf(SNAPSHOT)
27
+ FileUtils.mkdir_p(SNAPSHOT)
28
+ end
29
+
30
+ def copy_sources
31
+ FileUtils.cp_r(SUBJECT_LIB, SNAPSHOT)
32
+ FileUtils.cp_r(SUBJECT_EXE, SNAPSHOT)
33
+ end
34
+
35
+ def rename_entrypoints
36
+ File.rename(
37
+ File.join(SNAPSHOT, "lib", "evilution.rb"),
38
+ File.join(SNAPSHOT, "lib", "evilution_runtime.rb")
39
+ )
40
+ File.rename(
41
+ File.join(SNAPSHOT, "lib", "evilution"),
42
+ File.join(SNAPSHOT, "lib", "evilution_runtime")
43
+ )
44
+ File.rename(
45
+ File.join(SNAPSHOT, "exe", "evilution"),
46
+ File.join(SNAPSHOT, "exe", "evilution_runtime")
47
+ )
48
+ # exe/evil alias not needed in snapshot
49
+ evil_alias = File.join(SNAPSHOT, "exe", "evil")
50
+ FileUtils.rm_f(evil_alias)
51
+ end
52
+
53
+ def rewrite_sources
54
+ files = Dir.glob(File.join(SNAPSHOT, "**", "*.rb")) +
55
+ [File.join(SNAPSHOT, "exe", "evilution_runtime")]
56
+ files.uniq!
57
+ rewritten = 0
58
+ files.each do |path|
59
+ next unless File.file?(path)
60
+
61
+ original = File.read(path)
62
+ updated = rewrite(original)
63
+ next if updated == original
64
+
65
+ File.write(path, updated)
66
+ rewritten += 1
67
+ end
68
+ @rewritten_count = rewritten
69
+ end
70
+
71
+ def rewrite(source)
72
+ source
73
+ .gsub(/\bEvilution\b/, "EvilutionRuntime")
74
+ .gsub(%r{(require\s+)(["'])evilution(["'/])}, '\1\2evilution_runtime\3')
75
+ .gsub(%r{(require_relative\s+)(["'])((?:\.\./)*)evilution(["'/])}, '\1\2\3evilution_runtime\4')
76
+ end
77
+
78
+ def write_snapshot_sha
79
+ sha = `git -C #{ROOT} rev-parse HEAD`.strip
80
+ File.write(File.join(SNAPSHOT, ".snapshot_sha"), "#{sha}\n")
81
+ end
82
+
83
+ def print_summary
84
+ puts "snapshot built at #{SNAPSHOT}"
85
+ puts "files rewritten: #{@rewritten_count}"
86
+ end
87
+
88
+ main
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Throwaway driver (EV-yyd8): runs bin/evilution-self against every lib/evilution
5
+ # subdir to re-baseline self-mutation coverage. Per-dir logs go to
6
+ # tmp/baseline_logs/<dir>.self.log. Aggregate summary printed to stdout.
7
+
8
+ require "English"
9
+ require "fileutils"
10
+ require "shellwords"
11
+
12
+ ROOT = File.expand_path("..", __dir__)
13
+ LOG_DIR = File.join(ROOT, "tmp", "baseline_logs")
14
+ WRAPPER = File.join(ROOT, "bin", "evilution-self")
15
+
16
+ # Originally three Process.fork-using files (isolation/fork.rb,
17
+ # parallel/work_queue/worker.rb, baseline.rb) were skipped because subject
18
+ # grandchildren inherited the runtime marshal pipe write-end and hung the
19
+ # parent. EV-9qh1 fixed the protocol (length-prefix + polling waitpid), so the
20
+ # skip list is now empty.
21
+ SKIP_FILES = [].freeze
22
+
23
+ FileUtils.mkdir_p(LOG_DIR)
24
+
25
+ dirs = Dir.children(File.join(ROOT, "lib", "evilution"))
26
+ .select { |entry| File.directory?(File.join(ROOT, "lib", "evilution", entry)) }
27
+ .sort
28
+
29
+ results = []
30
+ dirs.each do |dir|
31
+ files = Dir.glob(File.join(ROOT, "lib", "evilution", dir, "**", "*.rb"))
32
+ files.reject! { |f| SKIP_FILES.include?(f) }
33
+
34
+ if files.empty?
35
+ puts "==> #{dir} (skipped — only fork-using files)"
36
+ results << { dir: dir, exitstatus: nil, log: nil, skipped: true }
37
+ next
38
+ end
39
+
40
+ log = File.join(LOG_DIR, "#{dir}.self.log")
41
+ cmd = [WRAPPER, "--strict", "--jobs=4", "--timeout=15", "--quiet-children", *files]
42
+ puts "==> #{dir} (#{files.length} files)"
43
+ pid = spawn(*cmd, out: log, err: %i[child out])
44
+ Process.wait(pid)
45
+ status = $CHILD_STATUS
46
+ results << { dir: dir, exitstatus: status.exitstatus, log: log, skipped: false }
47
+ puts " exit=#{status.exitstatus} log=#{log}"
48
+ end
49
+
50
+ # Toplevel files (lib/evilution/*.rb directly under lib/evilution/ — those that
51
+ # aren't in a subdir). EV-j2kz tagged this set as 'toplevel'.
52
+ toplevel_files = Dir.glob(File.join(ROOT, "lib", "evilution", "*.rb"))
53
+ toplevel_files.reject! { |f| SKIP_FILES.include?(f) }
54
+ unless toplevel_files.empty?
55
+ log = File.join(LOG_DIR, "toplevel.self.log")
56
+ cmd = [WRAPPER, "--strict", "--jobs=4", "--timeout=15", "--quiet-children", *toplevel_files]
57
+ puts "==> toplevel (#{toplevel_files.length} files)"
58
+ pid = spawn(*cmd, out: log, err: %i[child out])
59
+ Process.wait(pid)
60
+ status = $CHILD_STATUS
61
+ results << { dir: "toplevel", exitstatus: status.exitstatus, log: log, skipped: false }
62
+ puts " exit=#{status.exitstatus} log=#{log}"
63
+ end
64
+
65
+ puts
66
+ puts "=== summary ==="
67
+ results.each do |r|
68
+ if r[:skipped]
69
+ puts format("%<dir>-15s SKIPPED", dir: r[:dir])
70
+ next
71
+ end
72
+ measurable = `grep -E '^Mutations: ' #{Shellwords.escape(r[:log])} 2>/dev/null | tail -1`.strip
73
+ measurable = "NO_SUMMARY" if measurable.empty?
74
+ puts format("%<dir>-15s exit=%<exit>s %<measurable>s",
75
+ dir: r[:dir], exit: r[:exitstatus], measurable: measurable)
76
+ end
77
+
78
+ puts
79
+ puts "skipped files (fork-bug workaround): #{SKIP_FILES.map { |p| p.sub("#{ROOT}/", "") }.join(", ")}"
@@ -0,0 +1,54 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # EV-yyd8 fast validation: pick ONE small representative file per originally-
5
+ # crashing dir from EV-j2kz baseline, run bin/evilution-self against it, log
6
+ # results. Demonstrates the dual-runtime harness lifts the parent-crash issue
7
+ # for each previously-broken dir without requiring a multi-hour full re-run.
8
+
9
+ require "English"
10
+ require "fileutils"
11
+ require "shellwords"
12
+
13
+ ROOT = File.expand_path("..", __dir__)
14
+ LOG_DIR = File.join(ROOT, "tmp", "baseline_logs")
15
+ WRAPPER = File.join(ROOT, "bin", "evilution-self")
16
+
17
+ # One representative file per originally-crashing dir from EV-j2kz baseline.
18
+ # isolation/in_process.rb is the same file used in the spec verification step.
19
+ TARGETS = {
20
+ "isolation" => "lib/evilution/isolation/in_process.rb",
21
+ "result" => "lib/evilution/result/error_info.rb",
22
+ "compare" => "lib/evilution/compare/invalid_input.rb",
23
+ "parallel" => "lib/evilution/parallel/work_queue/collection_state.rb",
24
+ "ast" => "lib/evilution/ast/source_surgeon.rb",
25
+ "integration" => "lib/evilution/integration/loading.rb",
26
+ "runner" => "lib/evilution/runner/mutation_executor/neutralizer.rb",
27
+ "cli" => "lib/evilution/cli/result.rb",
28
+ "mutator" => "lib/evilution/mutator/operator.rb",
29
+ "toplevel" => "lib/evilution/memory.rb"
30
+ }.freeze
31
+
32
+ FileUtils.mkdir_p(LOG_DIR)
33
+
34
+ results = []
35
+ TARGETS.each do |dir, file|
36
+ full = File.join(ROOT, file)
37
+ log = File.join(LOG_DIR, "#{dir}.validation.log")
38
+ cmd = [WRAPPER, "--strict", "--jobs=1", "--timeout=15", "--quiet-children", full]
39
+ puts "==> #{dir}: #{file}"
40
+ pid = spawn(*cmd, out: log, err: %i[child out])
41
+ Process.wait(pid)
42
+ status = $CHILD_STATUS
43
+ results << { dir: dir, file: file, exitstatus: status.exitstatus, log: log }
44
+ puts " exit=#{status.exitstatus} log=#{log}"
45
+ end
46
+
47
+ puts
48
+ puts "=== validation summary ==="
49
+ results.each do |r|
50
+ measurable = `grep -E '^Mutations: ' #{Shellwords.escape(r[:log])} 2>/dev/null | tail -1`.strip
51
+ measurable = "NO_SUMMARY" if measurable.empty?
52
+ puts format("%<dir>-12s %<file>-55s exit=%<exit>s %<measurable>s",
53
+ dir: r[:dir], file: r[:file], exit: r[:exitstatus], measurable: measurable)
54
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: evilution
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.29.0
4
+ version: 0.30.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Denis Kiselev
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2026-05-06 00:00:00.000000000 Z
11
+ date: 2026-05-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diff-lcs
@@ -106,11 +106,13 @@ files:
106
106
  - docs/ast_pattern_syntax.md
107
107
  - docs/isolation.md
108
108
  - docs/mutation_density_benchmark.md
109
+ - docs/versioning.md
109
110
  - exe/evil
110
111
  - exe/evilution
111
112
  - lib/evilution.rb
112
113
  - lib/evilution/ast.rb
113
114
  - lib/evilution/ast/constant_names.rb
115
+ - lib/evilution/ast/heredoc_span.rb
114
116
  - lib/evilution/ast/inheritance_scanner.rb
115
117
  - lib/evilution/ast/parser.rb
116
118
  - lib/evilution/ast/pattern.rb
@@ -202,6 +204,8 @@ files:
202
204
  - lib/evilution/feedback.rb
203
205
  - lib/evilution/feedback/detector.rb
204
206
  - lib/evilution/feedback/messages.rb
207
+ - lib/evilution/feedback/setup_warning.rb
208
+ - lib/evilution/gem_detector.rb
205
209
  - lib/evilution/git.rb
206
210
  - lib/evilution/git/changed_files.rb
207
211
  - lib/evilution/hooks.rb
@@ -211,6 +215,7 @@ files:
211
215
  - lib/evilution/integration/base.rb
212
216
  - lib/evilution/integration/crash_detector.rb
213
217
  - lib/evilution/integration/loading.rb
218
+ - lib/evilution/integration/loading/body_call_neutralizer.rb
214
219
  - lib/evilution/integration/loading/concern_state_cleaner.rb
215
220
  - lib/evilution/integration/loading/constant_pinner.rb
216
221
  - lib/evilution/integration/loading/mutation_applier.rb
@@ -269,6 +274,7 @@ files:
269
274
  - lib/evilution/mutator.rb
270
275
  - lib/evilution/mutator/base.rb
271
276
  - lib/evilution/mutator/operator.rb
277
+ - lib/evilution/mutator/operator/argument_method_call_replacement.rb
272
278
  - lib/evilution/mutator/operator/argument_nil_substitution.rb
273
279
  - lib/evilution/mutator/operator/argument_removal.rb
274
280
  - lib/evilution/mutator/operator/arithmetic_replacement.rb
@@ -308,6 +314,7 @@ files:
308
314
  - lib/evilution/mutator/operator/integer_literal.rb
309
315
  - lib/evilution/mutator/operator/keyword_argument.rb
310
316
  - lib/evilution/mutator/operator/lambda_body.rb
317
+ - lib/evilution/mutator/operator/last_expression_removal.rb
311
318
  - lib/evilution/mutator/operator/local_variable_assignment.rb
312
319
  - lib/evilution/mutator/operator/loop_flip.rb
313
320
  - lib/evilution/mutator/operator/method_body_replacement.rb
@@ -371,6 +378,7 @@ files:
371
378
  - lib/evilution/reporter/cli/line_formatters.rb
372
379
  - lib/evilution/reporter/cli/line_formatters/duration.rb
373
380
  - lib/evilution/reporter/cli/line_formatters/efficiency.rb
381
+ - lib/evilution/reporter/cli/line_formatters/error_rate_warning.rb
374
382
  - lib/evilution/reporter/cli/line_formatters/feedback_footer.rb
375
383
  - lib/evilution/reporter/cli/line_formatters/header.rb
376
384
  - lib/evilution/reporter/cli/line_formatters/mutations.rb
@@ -457,6 +465,7 @@ files:
457
465
  - lib/evilution/runner/subject_pipeline.rb
458
466
  - lib/evilution/session.rb
459
467
  - lib/evilution/session/diff.rb
468
+ - lib/evilution/session/schema.rb
460
469
  - lib/evilution/session/store.rb
461
470
  - lib/evilution/source_ast_cache.rb
462
471
  - lib/evilution/spec_ast_cache.rb
@@ -466,7 +475,11 @@ files:
466
475
  - lib/evilution/temp_dir_tracker.rb
467
476
  - lib/evilution/version.rb
468
477
  - lib/tasks/memory_check.rake
478
+ - schema/evilution.config.schema.json
479
+ - script/build_runtime_snapshot
469
480
  - script/memory_check
481
+ - script/run_self_baseline
482
+ - script/run_self_validation
470
483
  - scripts/benchmark_density
471
484
  - scripts/benchmark_density.yml
472
485
  - scripts/compare_mutations