evilution 0.16.1 → 0.18.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 (52) hide show
  1. checksums.yaml +4 -4
  2. data/.beads/.migration-hint-ts +1 -1
  3. data/.beads/issues.jsonl +47 -46
  4. data/CHANGELOG.md +48 -0
  5. data/README.md +143 -50
  6. data/docs/ast_pattern_syntax.md +210 -0
  7. data/lib/evilution/ast/pattern/filter.rb +25 -0
  8. data/lib/evilution/ast/pattern/matcher.rb +107 -0
  9. data/lib/evilution/ast/pattern/parser.rb +185 -0
  10. data/lib/evilution/ast/pattern.rb +4 -0
  11. data/lib/evilution/ast/sorbet_sig_detector.rb +52 -0
  12. data/lib/evilution/cli.rb +400 -24
  13. data/lib/evilution/config.rb +43 -2
  14. data/lib/evilution/disable_comment.rb +90 -0
  15. data/lib/evilution/hooks/loader.rb +35 -0
  16. data/lib/evilution/hooks/registry.rb +60 -0
  17. data/lib/evilution/hooks.rb +58 -0
  18. data/lib/evilution/integration/base.rb +4 -0
  19. data/lib/evilution/integration/rspec.rb +6 -2
  20. data/lib/evilution/isolation/fork.rb +5 -0
  21. data/lib/evilution/mcp/session_diff_tool.rb +5 -35
  22. data/lib/evilution/mutator/base.rb +4 -1
  23. data/lib/evilution/mutator/operator/collection_return.rb +33 -0
  24. data/lib/evilution/mutator/operator/defined_check.rb +16 -0
  25. data/lib/evilution/mutator/operator/index_assignment_removal.rb +18 -0
  26. data/lib/evilution/mutator/operator/index_to_dig.rb +58 -0
  27. data/lib/evilution/mutator/operator/index_to_fetch.rb +30 -0
  28. data/lib/evilution/mutator/operator/keyword_argument.rb +91 -0
  29. data/lib/evilution/mutator/operator/mixin_removal.rb +2 -1
  30. data/lib/evilution/mutator/operator/multiple_assignment.rb +47 -0
  31. data/lib/evilution/mutator/operator/pattern_matching_alternative.rb +46 -0
  32. data/lib/evilution/mutator/operator/pattern_matching_array.rb +97 -0
  33. data/lib/evilution/mutator/operator/pattern_matching_guard.rb +44 -0
  34. data/lib/evilution/mutator/operator/regex_capture.rb +43 -0
  35. data/lib/evilution/mutator/operator/scalar_return.rb +37 -0
  36. data/lib/evilution/mutator/operator/splat_operator.rb +46 -0
  37. data/lib/evilution/mutator/operator/superclass_removal.rb +2 -1
  38. data/lib/evilution/mutator/operator/yield_statement.rb +51 -0
  39. data/lib/evilution/mutator/registry.rb +17 -3
  40. data/lib/evilution/parallel/pool.rb +7 -51
  41. data/lib/evilution/parallel/work_queue.rb +224 -0
  42. data/lib/evilution/reporter/cli.rb +22 -1
  43. data/lib/evilution/reporter/html.rb +76 -3
  44. data/lib/evilution/reporter/json.rb +23 -2
  45. data/lib/evilution/reporter/suggestion.rb +115 -1
  46. data/lib/evilution/result/summary.rb +20 -2
  47. data/lib/evilution/runner.rb +133 -13
  48. data/lib/evilution/session/diff.rb +85 -0
  49. data/lib/evilution/session/store.rb +5 -2
  50. data/lib/evilution/version.rb +1 -1
  51. data/lib/evilution.rb +23 -0
  52. metadata +28 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: '009f01f1d0ff623a8dc2730f05d23f5564118f0996e1d207d1c898a719579632'
4
- data.tar.gz: 89481ac5c9d0b8b344d14d2acbd320382abb5d0fa4fe3de2fea8a715154e9e0e
3
+ metadata.gz: f7dccdb22393202cfc4e6dc80d4066e88d5c500992b5cdbac0071bfcdf6f3e49
4
+ data.tar.gz: e0b5f72ab55296c76618e1e50d79a54a44e0df3e71b7280782399076e796cc3b
5
5
  SHA512:
6
- metadata.gz: 9de110591c9c23a86d20d521aa3002c7aa1743898ae7e4364f5c3ddfc7060a6907153cb050582bb2a3a7f07804f50f1bce1801e7e70df9ca892906065be0c9be
7
- data.tar.gz: d658b860c63f7226ae274db15c5abd417b41208043ed113fb0f484f335f377642999fadd2fd33190d24313d98498b75b3df3d2124a0620dc4859a73f3b5a97cb
6
+ metadata.gz: be52b1f27bde0281efbd40312be56df9f843d25260dc0e0bd615a22c419bd0728df7b0b02f78d0c02378a1710466e9b714b30c8201fa5f7c4a7cd3c14b99fa38
7
+ data.tar.gz: 74265ced2a848088153e22dc5a13d2b283ded3e7b8a8431ffcd364782aceef4461cfeed69abf5f1b39d22d64b26bdc4b708cbf7c6223f902fdeb9bebb572a9bb
@@ -1 +1 @@
1
- 1774720771
1
+ 1775191651
data/.beads/issues.jsonl CHANGED
@@ -26,7 +26,7 @@
26
26
  {"id":"EV-116","title":"Implement zsuper removal mutator","description":"Create a mutator for implicit super calls (zsuper — super with no parens). Mutations: remove the super call entirely. Prism forwarding_super_node.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:00.030638552+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T14:22:27.928183609+07:00","dependencies":[{"issue_id":"EV-116","depends_on_id":"EV-112","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
27
27
  {"id":"EV-117","title":"Implement rescue body replacement mutator","description":"Create a mutator that replaces rescue clause bodies with nil or re-raise. Tests whether the rescue handler logic is actually tested.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:07.741756241+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T09:46:31.420660224+07:00","dependencies":[{"issue_id":"EV-117","depends_on_id":"EV-89","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
28
28
  {"id":"EV-118","title":"Add compact/flatten and zip/product method swap pairs","description":"Add method swap pairs: compact↔flatten (remove nils vs flatten nesting), zip↔product (pairwise vs cartesian). Register in the collection method swap operator.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:09.488783588+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T13:07:37.800200558+07:00","dependencies":[{"issue_id":"EV-118","depends_on_id":"EV-96","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
29
- {"id":"EV-119","title":"Design hook registry and configuration API","description":"Design the hook system API: how hooks are registered (config file, Ruby API), what data they receive, and how errors are handled. Support at minimum: worker_process_start, mutation_insert_pre/post, and setup_integration_pre/post hook points.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:09.630400111+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:09.630400111+07:00","dependencies":[{"issue_id":"EV-119","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
29
+ {"id":"EV-119","title":"Design hook registry and configuration API","description":"Design the hook system API: how hooks are registered (config file, Ruby API), what data they receive, and how errors are handled. Support at minimum: worker_process_start, mutation_insert_pre/post, and setup_integration_pre/post hook points.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:09.630400111+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T21:23:56.689185157+07:00","dependencies":[{"issue_id":"EV-119","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
30
30
  {"id":"EV-12","title":"Resolve suggestion gap","description":"The workflow section instructs agents to read a suggestion field from survived[], but the JSON reporter output does not include suggestion (lib/evilution/reporter/json.rb only emits operator/file/line/status/duration/diff). Either add suggestion to the JSON output/schema or update the workflow steps to match the actual report fields. See GitHub issue #12.","status":"closed","priority":2,"issue_type":"bug","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-05T12:33:23.674094791+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-05T13:05:48.785616141+07:00","closed_at":"2026-03-05T13:05:48.785616141+07:00","close_reason":"Wired Suggestion into JSON reporter for survived mutations, updated README schema, added specs"}
31
31
  {"id":"EV-120","title":"Implement explicit super argument mutations","description":"Create a mutator for explicit super(args) calls. Mutations: remove arguments (super() with no args), remove individual arguments, replace super with zsuper. Prism super_node.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:10.245605293+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T14:27:56.442898048+07:00","dependencies":[{"issue_id":"EV-120","depends_on_id":"EV-112","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
32
32
  {"id":"EV-121","title":"Add RSpec suggestion templates for bitwise operator mutations","description":"Add concrete RSpec suggestion templates for survived bitwise operator mutations to the SuggestionReporter.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:12.673234672+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T14:16:14.791646944+07:00","dependencies":[{"issue_id":"EV-121","depends_on_id":"EV-105","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
@@ -34,87 +34,87 @@
34
34
  {"id":"EV-123","title":"Fix version mismatch between CLI and MCP JSON output","description":"CLI reports 0.12.0 but MCP JSON version field says 0.11.2. The version string in the MCP server response is hardcoded or reading from a stale source. Should read from Evilution::VERSION consistently. Identified in real-world comparison testing feedback.","status":"closed","priority":1,"issue_type":"bug","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:19.056996262+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:34:16.40564094+07:00","closed_at":"2026-03-23T11:34:16.40564094+07:00","close_reason":"Already fixed — all version references (MCP server, JSON reporter, HTML reporter) use Evilution::VERSION consistently. The 0.11.2 seen in feedback was likely a stale gem installation."}
35
35
  {"id":"EV-124","title":"Add first/last and keys/values method swap pairs","description":"Add orthogonal method swap pairs: first↔last (Array endpoints), keys↔values (Hash extraction). Register in the collection method swap operator.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:19.366299705+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T13:11:43.391612732+07:00","dependencies":[{"issue_id":"EV-124","depends_on_id":"EV-96","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
36
36
  {"id":"EV-125","title":"Add RSpec suggestion templates for super mutations","description":"Add concrete RSpec suggestion templates for survived super mutations to the SuggestionReporter.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:20.933060824+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T14:36:21.649380826+07:00","dependencies":[{"issue_id":"EV-125","depends_on_id":"EV-112","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
37
- {"id":"EV-126","title":"Implement hook registry module","description":"Create Evilution::Hooks::Registry that stores and dispatches hook callbacks. Support registering hooks by name, running hooks with context data, and error isolation (one failing hook shouldn't crash the run).","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:21.393514581+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:21.393514581+07:00","dependencies":[{"issue_id":"EV-126","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
37
+ {"id":"EV-126","title":"Implement hook registry module","description":"Create Evilution::Hooks::Registry that stores and dispatches hook callbacks. Support registering hooks by name, running hooks with context data, and error isolation (one failing hook shouldn't crash the run).","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:21.393514581+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T22:54:34.384022121+07:00","dependencies":[{"issue_id":"EV-126","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
38
38
  {"id":"EV-127","title":"Implement ensure clause removal mutator","description":"Create a mutator that removes ensure blocks from begin/ensure expressions. Tests whether cleanup code is actually necessary. Prism ensure_node.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:27.334061542+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T10:37:25.904594009+07:00","dependencies":[{"issue_id":"EV-127","depends_on_id":"EV-89","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
39
39
  {"id":"EV-128","title":"Visual progress bar for TTY execution","description":"Add a visual TTY progress bar during mutation testing showing mutation count, kills, elapsed time, and ETA. Mutant has had this since v0.14.2. Important for user experience during long-running mutation testing sessions.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:30.526136549+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:30.526136549+07:00"}
40
40
  {"id":"EV-129","title":"Add bang vs non-bang method mutations","description":"Create mutations that swap bang methods with their non-bang equivalents and vice versa (e.g., save! ↔ save, sort! ↔ sort, map! ↔ map, uniq! ↔ uniq). Tests whether the in-place vs copy semantics matter.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:30.959721048+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T13:16:36.661424217+07:00","dependencies":[{"issue_id":"EV-129","depends_on_id":"EV-100","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
41
41
  {"id":"EV-13","title":"Enable true per-mutation isolation with temp file copies","description":"Replace direct file writes with temp-dir + $LOAD_PATH isolation so multiple workers can mutate the same file in parallel. Remove per-file grouping from Pool#partition.","status":"closed","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-05T13:42:04.711580397+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-05T13:44:34.779951959+07:00","closed_at":"2026-03-05T13:44:34.779951959+07:00","close_reason":"Implemented temp file isolation via $LOAD_PATH and round-robin partition"}
42
- {"id":"EV-130","title":"Add worker_process_start hook point","description":"Fire the worker_process_start hook when a parallel worker process starts (after fork). This is the most important hook for Rails database isolation — users need to re-establish database connections after fork.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:31.360903708+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:31.360903708+07:00","dependencies":[{"issue_id":"EV-130","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
42
+ {"id":"EV-130","title":"Add worker_process_start hook point","description":"Fire the worker_process_start hook when a parallel worker process starts (after fork). This is the most important hook for Rails database isolation — users need to re-establish database connections after fork.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:31.360903708+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T23:07:00.267178228+07:00","dependencies":[{"issue_id":"EV-130","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
43
43
  {"id":"EV-131","title":"Epic: Index access operator mutations ([] / []=)","description":"Add mutations for index access operators. Mutant mutates [] to fetch/dig and []=. These surface real semantic differences (e.g., KeyError vs nil on missing key). Specifically called out in feedback as important.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:33.13561849+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:33.13561849+07:00"}
44
44
  {"id":"EV-132","title":"Add RSpec suggestion templates for exception handling mutations","description":"Add concrete RSpec suggestion templates for survived exception handling mutations to the SuggestionReporter.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:38.53663204+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T10:48:10.93836753+07:00","dependencies":[{"issue_id":"EV-132","depends_on_id":"EV-89","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
45
45
  {"id":"EV-133","title":"Implement TTY progress bar renderer","description":"Create a progress bar component that renders to TTY showing: [=====> ] 45/100 mutations | 38 killed | 2 survived | 00:23 elapsed | ~00:28 remaining. Detect TTY vs piped output and only show in TTY mode.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:40.177839247+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T15:05:19.015910008+07:00","dependencies":[{"issue_id":"EV-133","depends_on_id":"EV-128","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
46
- {"id":"EV-134","title":"Implement [] to fetch mutation","description":"Create a mutator that replaces hash/array [] access with .fetch(). This surfaces whether code handles missing keys properly. The [] vs fetch distinction was specifically called out in comparison feedback.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:42.107226515+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:42.107226515+07:00","dependencies":[{"issue_id":"EV-134","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
46
+ {"id":"EV-134","title":"Implement [] to fetch mutation","description":"Create a mutator that replaces hash/array [] access with .fetch(). This surfaces whether code handles missing keys properly. The [] vs fetch distinction was specifically called out in comparison feedback.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:42.107226515+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T20:25:10.80923459+07:00","dependencies":[{"issue_id":"EV-134","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
47
47
  {"id":"EV-135","title":"Add enumerable reduction method swaps","description":"Add method swap mutations for enumerable reductions: sum↔inject, count↔length↔size, detect↔find, select↔filter, collect↔map. Some may already exist; add the missing ones.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:42.397830812+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T13:31:17.723196272+07:00","dependencies":[{"issue_id":"EV-135","depends_on_id":"EV-100","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
48
- {"id":"EV-136","title":"Add mutation_insert_pre/post hook points","description":"Fire hooks before and after each mutation is inserted into source. Provides the mutation details (operator, location, original/mutated code) to the hook callback.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:44.656504163+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:44.656504163+07:00","dependencies":[{"issue_id":"EV-136","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
48
+ {"id":"EV-136","title":"Add mutation_insert_pre/post hook points","description":"Fire hooks before and after each mutation is inserted into source. Provides the mutation details (operator, location, original/mutated code) to the hook callback.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:44.656504163+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T00:28:05.530739933+07:00","dependencies":[{"issue_id":"EV-136","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
49
49
  {"id":"EV-137","title":"Integrate progress bar with Runner","description":"Wire the progress bar into Runner so it updates after each mutation result. Support both sequential and parallel execution modes. Ensure it doesn't interfere with verbose output.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:50.780537596+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T19:24:43.716640415+07:00","dependencies":[{"issue_id":"EV-137","depends_on_id":"EV-128","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
50
- {"id":"EV-138","title":"Implement [] to dig mutation","description":"Create a mutator that replaces nested [] access with .dig(). Tests whether nil propagation through nested access is handled.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:50.859337664+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:50.859337664+07:00","dependencies":[{"issue_id":"EV-138","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
50
+ {"id":"EV-138","title":"Implement [] to dig mutation","description":"Create a mutator that replaces nested [] access with .dig(). Tests whether nil propagation through nested access is handled.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:50.859337664+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T20:29:30.381299754+07:00","dependencies":[{"issue_id":"EV-138","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
51
51
  {"id":"EV-139","title":"Add to_s/to_i/to_f/to_a/to_h conversion method swaps","description":"Add mutations that swap type conversion methods with each other (e.g., to_s↔to_i, to_a↔to_h). Tests whether the correct type conversion is used.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:52.403463105+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T13:44:39.03275591+07:00","dependencies":[{"issue_id":"EV-139","depends_on_id":"EV-100","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
52
52
  {"id":"EV-14","title":"Add changelog_uri to gemspec metadata","description":"The published gem on RubyGems is missing the Changelog link. Add changelog_uri to spec.metadata in evilution.gemspec pointing to CHANGELOG.md on master.","status":"closed","priority":2,"issue_type":"bug","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-06T11:46:12.648668594+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-06T11:47:41.23691915+07:00","closed_at":"2026-03-06T11:47:41.23691915+07:00","close_reason":"Added changelog_uri to gemspec"}
53
- {"id":"EV-140","title":"Add setup_integration_pre/post hook points","description":"Fire hooks before and after the test integration is set up. Allows custom environment configuration before tests run.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:53.595178841+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:17:53.595178841+07:00","dependencies":[{"issue_id":"EV-140","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
53
+ {"id":"EV-140","title":"Add setup_integration_pre/post hook points","description":"Fire hooks before and after the test integration is set up. Allows custom environment configuration before tests run.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:17:53.595178841+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T00:45:12.894118119+07:00","dependencies":[{"issue_id":"EV-140","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
54
54
  {"id":"EV-141","title":"Epic: Pattern matching mutations (case/in)","description":"Add mutation operators for Ruby 3.x+ pattern matching expressions (case/in). Mutant mutates guards, alternatives, and predicates in pattern matching. Important as pattern matching adoption grows.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:00.138078298+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:00.138078298+07:00"}
55
- {"id":"EV-142","title":"Implement []= removal mutation","description":"Create a mutator that removes []= (index assignment) statements. Tests whether the assignment is actually necessary.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:01.34824668+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:01.34824668+07:00","dependencies":[{"issue_id":"EV-142","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
55
+ {"id":"EV-142","title":"Implement []= removal mutation","description":"Create a mutator that removes []= (index assignment) statements. Tests whether the assignment is actually necessary.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:01.34824668+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T20:47:29.117134657+07:00","dependencies":[{"issue_id":"EV-142","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
56
56
  {"id":"EV-143","title":"Add --no-progress flag to disable progress bar","description":"Add CLI flag and config option to disable the progress bar for CI/piped environments where TTY detection might not work correctly.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:01.773000995+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T19:30:09.471623389+07:00","dependencies":[{"issue_id":"EV-143","depends_on_id":"EV-128","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
57
57
  {"id":"EV-144","title":"Add send vs public_send method swap","description":"Add a mutation that swaps send with public_send and vice versa. Tests whether the method visibility bypass is intentional.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:03.825429179+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T13:54:46.379099536+07:00","dependencies":[{"issue_id":"EV-144","depends_on_id":"EV-100","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
58
- {"id":"EV-145","title":"Add hooks configuration to .evilution.yml","description":"Allow hooks to be specified in .evilution.yml config file. Support both inline Ruby blocks and file paths to Ruby scripts. Example: hooks: { worker_process_start: 'config/evilution_hooks.rb' }.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:04.207200619+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:04.207200619+07:00","dependencies":[{"issue_id":"EV-145","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
59
- {"id":"EV-146","title":"Add RSpec suggestion templates for index access mutations","description":"Add concrete RSpec suggestion templates for survived index access mutations to the SuggestionReporter.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:11.229320728+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:11.229320728+07:00","dependencies":[{"issue_id":"EV-146","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
60
- {"id":"EV-147","title":"Implement pattern matching guard mutation","description":"Mutate guard clauses in pattern matching (in pattern if guard). Mutations: remove guard (always match), negate guard. Prism in_node with guard.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:12.368560689+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:12.368560689+07:00","dependencies":[{"issue_id":"EV-147","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
58
+ {"id":"EV-145","title":"Add hooks configuration to .evilution.yml","description":"Allow hooks to be specified in .evilution.yml config file. Support both inline Ruby blocks and file paths to Ruby scripts. Example: hooks: { worker_process_start: 'config/evilution_hooks.rb' }.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:04.207200619+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T00:57:29.643350761+07:00","dependencies":[{"issue_id":"EV-145","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
59
+ {"id":"EV-146","title":"Add RSpec suggestion templates for index access mutations","description":"Add concrete RSpec suggestion templates for survived index access mutations to the SuggestionReporter.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:11.229320728+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T21:10:50.330156341+07:00","dependencies":[{"issue_id":"EV-146","depends_on_id":"EV-131","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
60
+ {"id":"EV-147","title":"Implement pattern matching guard mutation","description":"Mutate guard clauses in pattern matching (in pattern if guard). Mutations: remove guard (always match), negate guard. Prism in_node with guard.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:12.368560689+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T10:27:48.916121107+07:00","dependencies":[{"issue_id":"EV-147","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
61
61
  {"id":"EV-148","title":"Session recording and history","description":"Store JSON results per run in .evilution/results/ with CLI commands to list, show, and garbage-collect past sessions. Mutant v1.0.0 has this. Enables trend analysis and regression detection across runs.","status":"closed","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:13.658761141+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T01:20:56.545069251+07:00","closed_at":"2026-03-28T01:20:56.545069251+07:00","close_reason":"GH #294 closed by user"}
62
- {"id":"EV-149","title":"Add RSpec tests for hooks system","description":"Comprehensive test coverage for the hooks system: registration, dispatch, error isolation, configuration loading, all hook points firing at correct times.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:16.004153638+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:16.004153638+07:00","dependencies":[{"issue_id":"EV-149","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
62
+ {"id":"EV-149","title":"Add RSpec tests for hooks system","description":"Comprehensive test coverage for the hooks system: registration, dispatch, error isolation, configuration loading, all hook points firing at correct times.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:16.004153638+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T01:21:30.147192237+07:00","dependencies":[{"issue_id":"EV-149","depends_on_id":"EV-110","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
63
63
  {"id":"EV-15","title":"Add line-range targeting (file:line-line syntax)","description":"Parse line-range syntax in CLI, store in Config, filter subjects in Runner. GH #29.","status":"closed","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-08T00:36:29.164188342+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-08T00:38:02.739833414+07:00","closed_at":"2026-03-08T00:38:02.739833414+07:00","close_reason":"Implemented line-range targeting in CLI, Config, and Runner with full test coverage"}
64
64
  {"id":"EV-150","title":"Implement session result storage","description":"After each mutation run (when --save-session is passed), save a JSON file to .evilution/results/<timestamp>-<hash>.json containing: version, timestamp, git context (branch, commit SHA), summary statistics, and survived mutation details.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:23.433170933+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-24T00:32:49.095176663+07:00","dependencies":[{"issue_id":"EV-150","depends_on_id":"EV-148","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
65
- {"id":"EV-151","title":"Implement pattern matching alternative mutation","description":"Mutate pattern alternatives (in pat1 | pat2). Mutations: remove each alternative individually, swap order. Prism alternation_pattern_node.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:23.447046732+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:23.447046732+07:00","dependencies":[{"issue_id":"EV-151","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
65
+ {"id":"EV-151","title":"Implement pattern matching alternative mutation","description":"Mutate pattern alternatives (in pat1 | pat2). Mutations: remove each alternative individually, swap order. Prism alternation_pattern_node.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:23.447046732+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T10:45:02.759245169+07:00","dependencies":[{"issue_id":"EV-151","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
66
66
  {"id":"EV-152","title":"Epic: Type-aware return value mutations","description":"Add mutations that replace return values with type-appropriate empty/zero values: Array→[], Hash→{}, String→\"\", Integer→0, Float→0.0, true→false. Mutant does this extensively; Evilution only does body→nil.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:23.546834696+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:23.546834696+07:00"}
67
67
  {"id":"EV-153","title":"Epic: Dynamic work allocation for parallel execution","description":"Replace static batch-based work distribution with a shared work queue for dynamic load balancing. Mutant uses a shared queue where workers pull the next mutation as they complete work. Evilution's current static batching can lead to uneven utilization when mutation execution times vary.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:26.946371704+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:26.946371704+07:00"}
68
- {"id":"EV-154","title":"Implement type-aware return mutations for collection types","description":"When a method body returns an Array literal or Hash literal, also generate mutations returning the empty version ([] or {}). Detect by return value node type.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:31.525962391+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:31.525962391+07:00","dependencies":[{"issue_id":"EV-154","depends_on_id":"EV-152","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
69
- {"id":"EV-155","title":"Implement pattern matching find/array pattern mutations","description":"Mutate find and array patterns: remove individual pattern elements, replace with wildcard (_). Prism find_pattern_node, array_pattern_node.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:33.136069529+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:33.136069529+07:00","dependencies":[{"issue_id":"EV-155","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
68
+ {"id":"EV-154","title":"Implement type-aware return mutations for collection types","description":"When a method body returns an Array literal or Hash literal, also generate mutations returning the empty version ([] or {}). Detect by return value node type.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:31.525962391+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T16:29:31.709023703+07:00","dependencies":[{"issue_id":"EV-154","depends_on_id":"EV-152","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
69
+ {"id":"EV-155","title":"Implement pattern matching find/array pattern mutations","description":"Mutate find and array patterns: remove individual pattern elements, replace with wildcard (_). Prism find_pattern_node, array_pattern_node.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:33.136069529+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T10:49:55.941063007+07:00","dependencies":[{"issue_id":"EV-155","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
70
70
  {"id":"EV-156","title":"Add 'evilution session list' command","description":"Add a CLI subcommand that lists past session results with date, target, mutation count, score, and duration. Support --limit and --since filters.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:35.453549801+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-24T09:01:22.324682217+07:00","dependencies":[{"issue_id":"EV-156","depends_on_id":"EV-148","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
71
- {"id":"EV-157","title":"Implement shared work queue with pipe-based IPC","description":"Create a work queue that distributes mutations to worker processes dynamically. Use pipe-based IPC (or DRb) so workers pull the next mutation when ready, rather than receiving a pre-assigned batch.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:35.963687077+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:35.963687077+07:00","dependencies":[{"issue_id":"EV-157","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
72
- {"id":"EV-158","title":"Implement type-aware return mutations for scalar types","description":"When a method body returns a String, Integer, or Float literal, also generate mutations returning the zero/empty value ('', 0, 0.0). Detect by return value node type.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:43.59763546+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:43.59763546+07:00","dependencies":[{"issue_id":"EV-158","depends_on_id":"EV-152","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
73
- {"id":"EV-159","title":"Add RSpec suggestion templates for pattern matching mutations","description":"Add concrete RSpec suggestion templates for survived pattern matching mutations.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:45.083995741+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:45.083995741+07:00","dependencies":[{"issue_id":"EV-159","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
71
+ {"id":"EV-157","title":"Implement shared work queue with pipe-based IPC","description":"Create a work queue that distributes mutations to worker processes dynamically. Use pipe-based IPC (or DRb) so workers pull the next mutation when ready, rather than receiving a pre-assigned batch.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:35.963687077+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-31T00:46:53.163290251+07:00","dependencies":[{"issue_id":"EV-157","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
72
+ {"id":"EV-158","title":"Implement type-aware return mutations for scalar types","description":"When a method body returns a String, Integer, or Float literal, also generate mutations returning the zero/empty value ('', 0, 0.0). Detect by return value node type.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:43.59763546+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T17:28:18.637758436+07:00","dependencies":[{"issue_id":"EV-158","depends_on_id":"EV-152","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
73
+ {"id":"EV-159","title":"Add RSpec suggestion templates for pattern matching mutations","description":"Add concrete RSpec suggestion templates for survived pattern matching mutations.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:45.083995741+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T11:33:37.260966394+07:00","dependencies":[{"issue_id":"EV-159","depends_on_id":"EV-141","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
74
74
  {"id":"EV-16","title":"Remove file-discovery logic from Integration::RSpec (GH #33)","description":"Integration::RSpec has detect_test_files, spec_file_candidates, and fallback_spec_dir that guess which specs to run. With precise targeting, agents can pass spec files directly. Simplify or remove this guessing logic, possibly adding a --spec flag.","status":"closed","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-08T19:17:27.268579626+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-09T18:13:46.899195957+07:00","closed_at":"2026-03-09T18:13:46.899195957+07:00","close_reason":"Completed via PR #38 (tracked as EV-17)"}
75
75
  {"id":"EV-160","title":"Add 'evilution session show' command","description":"Add a CLI subcommand that displays the full report for a specific past session, including all survived mutations with diffs.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:45.851348485+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-24T12:24:53.120184549+07:00","dependencies":[{"issue_id":"EV-160","depends_on_id":"EV-148","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
76
- {"id":"EV-161","title":"Add work-stealing for idle workers","description":"When a worker's local queue is empty, allow it to pull work from the shared queue immediately rather than waiting. Track per-worker completion rates for monitoring.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:47.426119432+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:47.426119432+07:00","dependencies":[{"issue_id":"EV-161","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
77
- {"id":"EV-162","title":"Add RSpec suggestion templates for type-aware return mutations","description":"Add concrete RSpec suggestion templates for survived type-aware return mutations to the SuggestionReporter.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:53.50501093+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:53.50501093+07:00","dependencies":[{"issue_id":"EV-162","depends_on_id":"EV-152","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
76
+ {"id":"EV-161","title":"Add work-stealing for idle workers","description":"When a worker's local queue is empty, allow it to pull work from the shared queue immediately rather than waiting. Track per-worker completion rates for monitoring.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:47.426119432+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-31T11:40:34.186342998+07:00","dependencies":[{"issue_id":"EV-161","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
77
+ {"id":"EV-162","title":"Add RSpec suggestion templates for type-aware return mutations","description":"Add concrete RSpec suggestion templates for survived type-aware return mutations to the SuggestionReporter.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:53.50501093+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T21:05:48.502034781+07:00","dependencies":[{"issue_id":"EV-162","depends_on_id":"EV-152","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
78
78
  {"id":"EV-163","title":"Add 'evilution session gc' command","description":"Add a CLI subcommand to garbage-collect old session results. Support --older-than flag (e.g., --older-than 30d). Default to keeping all results.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:56.398453511+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-24T13:45:03.75407328+07:00","dependencies":[{"issue_id":"EV-163","depends_on_id":"EV-148","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
79
79
  {"id":"EV-164","title":"Epic: AST pattern language for ignore_patterns","description":"Implement a pattern language for ignore_patterns configuration, similar to Mutant's (e.g., send{selector=log}, send{receiver=send{selector=logger}}). Allows precise, semantic exclusion of mutations on logging, debugging, or infrastructure code without requiring file/line targeting.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:56.583664516+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:56.583664516+07:00"}
80
- {"id":"EV-165","title":"Update Parallel::Pool to use dynamic queue","description":"Refactor Parallel::Pool to use the new dynamic work queue instead of static batch distribution. Maintain backward compatibility with the existing API (results should be identical, just better distributed).","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:57.644578151+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:18:57.644578151+07:00","dependencies":[{"issue_id":"EV-165","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
81
- {"id":"EV-166","title":"Design AST pattern language syntax","description":"Design the pattern matching DSL syntax for ignore_patterns. Support at minimum: node type matching, attribute matching (selector, receiver), nested patterns, and wildcards. Document the syntax with examples.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:04.486430975+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:04.486430975+07:00","dependencies":[{"issue_id":"EV-166","depends_on_id":"EV-164","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
82
- {"id":"EV-167","title":"Add efficiency metrics to summary output","description":"Add killtime/runtime efficiency percentage and mutations/second rate to the summary output. Mutant reports these. Helps users understand mutation testing overhead and optimize configuration. Calculate: efficiency = (time spent in test execution / total runtime) * 100%, rate = total_mutations / total_seconds.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:10.074542778+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:10.074542778+07:00"}
83
- {"id":"EV-168","title":"Add parallel execution metrics","description":"Track and report per-worker mutation counts, idle time, and utilization percentage. Include in verbose output to help users tune their --jobs setting.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:11.84738201+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:11.84738201+07:00","dependencies":[{"issue_id":"EV-168","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
84
- {"id":"EV-169","title":"Implement AST pattern parser","description":"Parse the pattern language strings into a matcher object that can be evaluated against Prism AST nodes. Support: node type (send, lvar), attribute filters ({selector=log}), nested matchers.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:15.548202079+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:15.548202079+07:00","dependencies":[{"issue_id":"EV-169","depends_on_id":"EV-164","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
80
+ {"id":"EV-165","title":"Update Parallel::Pool to use dynamic queue","description":"Refactor Parallel::Pool to use the new dynamic work queue instead of static batch distribution. Maintain backward compatibility with the existing API (results should be identical, just better distributed).","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:18:57.644578151+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-31T12:38:19.035204686+07:00","dependencies":[{"issue_id":"EV-165","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
81
+ {"id":"EV-166","title":"Design AST pattern language syntax","description":"Design the pattern matching DSL syntax for ignore_patterns. Support at minimum: node type matching, attribute matching (selector, receiver), nested patterns, and wildcards. Document the syntax with examples.","design":"See docs/ast_pattern_syntax.md for full syntax spec. Key decisions: Prism-native node type names, unquoted attribute values, alternatives with |, nested patterns for structural matching, _ and ** wildcards, negation with !, AND across attributes / OR within values. Grammar in EBNF included.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:04.486430975+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T11:45:10.017653608+07:00","dependencies":[{"issue_id":"EV-166","depends_on_id":"EV-164","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
82
+ {"id":"EV-167","title":"Add efficiency metrics to summary output","description":"Add killtime/runtime efficiency percentage and mutations/second rate to the summary output. Mutant reports these. Helps users understand mutation testing overhead and optimize configuration. Calculate: efficiency = (time spent in test execution / total runtime) * 100%, rate = total_mutations / total_seconds.","status":"in_progress","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:10.074542778+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T11:59:25.442023723+07:00"}
83
+ {"id":"EV-168","title":"Add parallel execution metrics","description":"Track and report per-worker mutation counts, idle time, and utilization percentage. Include in verbose output to help users tune their --jobs setting.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:11.84738201+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-31T16:23:30.539924782+07:00","dependencies":[{"issue_id":"EV-168","depends_on_id":"EV-153","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
84
+ {"id":"EV-169","title":"Implement AST pattern parser","description":"Parse the pattern language strings into a matcher object that can be evaluated against Prism AST nodes. Support: node type (send, lvar), attribute filters ({selector=log}), nested matchers.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:15.548202079+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T12:04:08.595004056+07:00","dependencies":[{"issue_id":"EV-169","depends_on_id":"EV-164","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
85
85
  {"id":"EV-17","title":"Remove file-discovery logic from Integration::RSpec","description":"Add --spec flag, simplify RSpec integration by removing detect_test_files heuristics. GH #33","status":"closed","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-09T00:41:29.880486333+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-09T00:43:21.229172712+07:00","closed_at":"2026-03-09T00:43:21.229172712+07:00","close_reason":"Removed ~60 lines of file-discovery logic from Integration::RSpec, added --spec CLI flag, spec_files config, and wired through Runner"}
86
86
  {"id":"EV-170","title":"Environment diagnostic commands","description":"Add diagnostic/inspection commands similar to Mutant's environment tools. Helps users understand what Evilution sees before running a full mutation test.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:19.537979519+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:19.537979519+07:00"}
87
87
  {"id":"EV-171","title":"Integrate AST pattern filter with mutation generation","description":"Before generating mutations, check if the target AST node matches any ignore_pattern. Skip matching nodes. Report skipped count in summary.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:24.909224128+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:24.909224128+07:00","dependencies":[{"issue_id":"EV-171","depends_on_id":"EV-164","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
88
88
  {"id":"EV-172","title":"Support # evilution:disable source comments","description":"Allow users to add # evilution:disable comments in source code to skip mutations for specific methods or lines. Mutant supports # mutant:disable for per-method opt-out. Should support: method-level (comment before def), line-level (inline comment), and block-level (disable/enable pairs).","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:25.957514857+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:25.957514857+07:00"}
89
- {"id":"EV-173","title":"Add 'evilution environment show' command","description":"Display the resolved configuration: loaded config file, CLI overrides, effective values for all settings (jobs, target, integration, etc.).","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:30.633766429+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:30.633766429+07:00","dependencies":[{"issue_id":"EV-173","depends_on_id":"EV-170","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
90
- {"id":"EV-174","title":"Implement comment-based disable detection","description":"Scan source files for # evilution:disable comments. Support three forms: method-level (comment on line before def), line-level (inline # evilution:disable), and range (# evilution:disable / # evilution:enable pairs). Store disabled ranges per file.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:35.174813233+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:35.174813233+07:00","dependencies":[{"issue_id":"EV-174","depends_on_id":"EV-172","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
91
- {"id":"EV-175","title":"Add ignore_patterns to .evilution.yml config","description":"Add ignore_patterns as a config key in .evilution.yml. Accept an array of pattern strings. Example: ignore_patterns: ['send{selector=log}', 'send{receiver=send{selector=logger}}'].","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:35.758598835+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:35.758598835+07:00","dependencies":[{"issue_id":"EV-175","depends_on_id":"EV-164","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
92
- {"id":"EV-176","title":"Add 'evilution subjects' command","description":"List all subjects (classes/methods) that would be mutated for the given target. Shows what mutations would be generated without actually running tests.","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:44.530116644+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:44.530116644+07:00","dependencies":[{"issue_id":"EV-176","depends_on_id":"EV-170","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
93
- {"id":"EV-177","title":"Filter mutations against disabled ranges","description":"Before generating mutations, check if the target source location falls within a disabled range. Skip mutation generation for disabled locations. Report skipped count in summary.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:46.006587202+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:46.006587202+07:00","dependencies":[{"issue_id":"EV-177","depends_on_id":"EV-172","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
89
+ {"id":"EV-173","title":"Add 'evilution environment show' command","description":"Display the resolved configuration: loaded config file, CLI overrides, effective values for all settings (jobs, target, integration, etc.).","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:30.633766429+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T12:35:49.003716036+07:00","dependencies":[{"issue_id":"EV-173","depends_on_id":"EV-170","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
90
+ {"id":"EV-174","title":"Implement comment-based disable detection","description":"Scan source files for # evilution:disable comments. Support three forms: method-level (comment on line before def), line-level (inline # evilution:disable), and range (# evilution:disable / # evilution:enable pairs). Store disabled ranges per file.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:35.174813233+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T21:38:13.512669264+07:00","dependencies":[{"issue_id":"EV-174","depends_on_id":"EV-172","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
91
+ {"id":"EV-175","title":"Add ignore_patterns to .evilution.yml config","description":"Add ignore_patterns as a config key in .evilution.yml. Accept an array of pattern strings. Example: ignore_patterns: ['send{selector=log}', 'send{receiver=send{selector=logger}}'].","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:35.758598835+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-30T13:57:11.398457981+07:00","dependencies":[{"issue_id":"EV-175","depends_on_id":"EV-164","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
92
+ {"id":"EV-176","title":"Add 'evilution subjects' command","description":"List all subjects (classes/methods) that would be mutated for the given target. Shows what mutations would be generated without actually running tests.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:44.530116644+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T13:40:26.15472488+07:00","dependencies":[{"issue_id":"EV-176","depends_on_id":"EV-170","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
93
+ {"id":"EV-177","title":"Filter mutations against disabled ranges","description":"Before generating mutations, check if the target source location falls within a disabled range. Skip mutation generation for disabled locations. Report skipped count in summary.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:46.006587202+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T22:42:25.830104359+07:00","dependencies":[{"issue_id":"EV-177","depends_on_id":"EV-172","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
94
94
  {"id":"EV-178","title":"Epic: Rich subject expression language","description":"Implement a rich expression language for subject matching similar to Mutant's: namespace wildcards (Foo::Bar*), method-type selectors (Foo# for instance, Foo. for class methods), descendant matching (descendants:Foo). Currently Evilution supports method names and file paths but lacks wildcard and type selectors.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:48.801608223+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:48.801608223+07:00"}
95
- {"id":"EV-179","title":"Add --show-disabled flag to report disabled mutations","description":"Add a CLI flag that reports which mutations were skipped due to disable comments, so users can audit their disable annotations.","status":"open","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:56.450400314+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:56.450400314+07:00","dependencies":[{"issue_id":"EV-179","depends_on_id":"EV-172","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
95
+ {"id":"EV-179","title":"Add --show-disabled flag to report disabled mutations","description":"Add a CLI flag that reports which mutations were skipped due to disable comments, so users can audit their disable annotations.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:56.450400314+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T23:19:10.347361729+07:00","dependencies":[{"issue_id":"EV-179","depends_on_id":"EV-172","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
96
96
  {"id":"EV-18","title":"Add method-name targeting (Class#method) (GH #30)","description":"Allow specifying a fully-qualified method name: evilution run Foo::Bar#calculate. Resolve name to file and line range, then mutate only that method. Lower priority since it requires name-to-file resolution which can be ambiguous with reopened classes or metaprogramming. Update README, --help, and CHANGELOG.","status":"closed","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-09T23:49:31.827723147+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-16T10:11:01.311634237+07:00","closed_at":"2026-03-16T10:11:01.311634237+07:00","close_reason":"Already merged and released in v0.4.0"}
97
- {"id":"EV-180","title":"Add 'evilution tests list' command","description":"List all detected test files and test examples that would be run. Useful for verifying test discovery is working correctly.","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:56.667492485+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:19:56.667492485+07:00","dependencies":[{"issue_id":"EV-180","depends_on_id":"EV-170","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
97
+ {"id":"EV-180","title":"Add 'evilution tests list' command","description":"List all detected test files and test examples that would be run. Useful for verifying test discovery is working correctly.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:19:56.667492485+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T15:56:28.450828915+07:00","dependencies":[{"issue_id":"EV-180","depends_on_id":"EV-170","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
98
98
  {"id":"EV-181","title":"Sorbet type signature awareness for mutations","description":"Detect and unwrap Sorbet type signatures (sig { ... }) before mutation. Mutant automatically skips mutations inside sig blocks and handles typed codebases without special configuration. Evilution should skip sig blocks to avoid generating useless mutations on type annotations.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:07.254888519+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:07.254888519+07:00"}
99
- {"id":"EV-182","title":"Add 'evilution util mutation' preview command","description":"Add a utility command that previews mutations for a code snippet without running tests: evilution util mutation -e 'def foo; x + y; end'. Shows all mutations that would be generated. Mutant has this. Useful for understanding operator behavior and debugging mutation generation.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:08.026842032+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:08.026842032+07:00"}
99
+ {"id":"EV-182","title":"Add 'evilution util mutation' preview command","description":"Add a utility command that previews mutations for a code snippet without running tests: evilution util mutation -e 'def foo; x + y; end'. Shows all mutations that would be generated. Mutant has this. Useful for understanding operator behavior and debugging mutation generation.","status":"in_progress","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:08.026842032+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T09:18:13.193559394+07:00"}
100
100
  {"id":"EV-183","title":"Implement namespace wildcard matching (Foo::Bar*)","description":"Support wildcard patterns in --target that match all classes/modules under a namespace. E.g., Foo::Bar* matches Foo::Bar, Foo::BarBaz, Foo::Bar::Qux.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:09.50500441+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T23:30:28.435713182+07:00","dependencies":[{"issue_id":"EV-183","depends_on_id":"EV-178","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
101
- {"id":"EV-184","title":"Detect Sorbet sig blocks in source","description":"Identify Sorbet sig { ... } blocks (send nodes with receiver T and method sig) in source files. Store their byte ranges for exclusion.","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:18.062074984+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:18.062074984+07:00","dependencies":[{"issue_id":"EV-184","depends_on_id":"EV-181","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
101
+ {"id":"EV-184","title":"Detect Sorbet sig blocks in source","description":"Identify Sorbet sig { ... } blocks (send nodes with receiver T and method sig) in source files. Store their byte ranges for exclusion.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:18.062074984+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T00:05:05.041117033+07:00","dependencies":[{"issue_id":"EV-184","depends_on_id":"EV-181","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
102
102
  {"id":"EV-185","title":"Cross-run comparison and diffing","description":"Add ability to diff between two session results to show mutation coverage changes over time. Specifically requested in comparison testing feedback. Show: new mutations, removed mutations, changed results (killed→survived or vice versa).","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:18.414861607+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:18.414861607+07:00"}
103
103
  {"id":"EV-186","title":"Implement method-type selectors (Foo#, Foo.)","description":"Support targeting all instance methods of a class (Foo#) or all class methods (Foo.) without specifying individual method names.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:21.178494367+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T23:02:33.070915314+07:00","dependencies":[{"issue_id":"EV-186","depends_on_id":"EV-178","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
104
- {"id":"EV-187","title":"Implement session result diffing engine","description":"Create a diff engine that compares two session result JSON files and produces: new mutations (in B but not A), removed mutations (in A but not B), status changes (killed→survived, survived→killed), and score delta.","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:26.707985667+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:26.707985667+07:00","dependencies":[{"issue_id":"EV-187","depends_on_id":"EV-185","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
105
- {"id":"EV-188","title":"Skip mutation generation inside sig blocks","description":"Filter out any mutation whose source location falls within a Sorbet sig block. Report skipped count separately in verbose output.","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:28.716852636+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:28.716852636+07:00","dependencies":[{"issue_id":"EV-188","depends_on_id":"EV-181","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
104
+ {"id":"EV-187","title":"Implement session result diffing engine","description":"Create a diff engine that compares two session result JSON files and produces: new mutations (in B but not A), removed mutations (in A but not B), status changes (killed→survived, survived→killed), and score delta.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:26.707985667+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T00:35:17.712475445+07:00","dependencies":[{"issue_id":"EV-187","depends_on_id":"EV-185","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
105
+ {"id":"EV-188","title":"Skip mutation generation inside sig blocks","description":"Filter out any mutation whose source location falls within a Sorbet sig block. Report skipped count separately in verbose output.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:28.716852636+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T00:21:25.655821536+07:00","dependencies":[{"issue_id":"EV-188","depends_on_id":"EV-181","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
106
106
  {"id":"EV-189","title":"Implement descendant matching (descendants:Foo)","description":"Support descendants:Foo syntax to match Foo and all classes that inherit from Foo. Requires scanning the codebase for class inheritance.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:30.943382606+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T22:39:55.192457857+07:00","dependencies":[{"issue_id":"EV-189","depends_on_id":"EV-178","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
107
107
  {"id":"EV-19","title":"Add method-name targeting (--target flag)","description":"Users can target a specific method for mutation testing via --target METHOD flag. Matches against Subject.name.","status":"closed","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-10T00:09:57.091870734+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-10T00:10:02.637447023+07:00","closed_at":"2026-03-10T00:10:02.637447023+07:00","close_reason":"Implemented --target flag in CLI, Config.target? predicate, Runner.filter_by_target, README docs, and specs"}
108
- {"id":"EV-190","title":"Add 'evilution session diff' CLI command","description":"Add CLI subcommand: evilution session diff <session-a> <session-b>. Output the comparison in a readable format with color-coded changes.","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:38.753251207+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:38.753251207+07:00","dependencies":[{"issue_id":"EV-190","depends_on_id":"EV-185","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
108
+ {"id":"EV-190","title":"Add 'evilution session diff' CLI command","description":"Add CLI subcommand: evilution session diff <session-a> <session-b>. Output the comparison in a readable format with color-coded changes.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:38.753251207+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T08:33:44.437112284+07:00","dependencies":[{"issue_id":"EV-190","depends_on_id":"EV-185","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
109
109
  {"id":"EV-191","title":"Verify and ensure Ruby 4.0 compatibility","description":"Test Evilution against Ruby 4.0 (when available) and fix any compatibility issues. Mutant already supports Ruby 4.0. Key areas: Prism parser compatibility with new syntax, frozen string literals by default, any deprecated API usage.","status":"closed","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:39.786215101+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T17:15:21.121499298+07:00","closed_at":"2026-03-23T17:15:21.121499298+07:00","close_reason":"No action needed — Ruby 4.0 already supported and tested in CI (matrix includes 4.0.2). The gap analysis claim of 'not yet tested' was outdated."}
110
110
  {"id":"EV-192","title":"Implement source glob matching (source:lib/**/*.rb)","description":"Support source: prefix for file glob patterns in --target, matching mutant's source:lib/**/*.rb syntax.","status":"in_progress","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:41.326339048+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T22:21:33.599617614+07:00","dependencies":[{"issue_id":"EV-192","depends_on_id":"EV-178","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
111
- {"id":"EV-193","title":"Add cross-run comparison to HTML report","description":"Extend the HTML reporter to optionally include comparison data from a baseline session, highlighting regressions (newly survived mutations) in red.","status":"open","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:49.187589087+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:49.187589087+07:00","dependencies":[{"issue_id":"EV-193","depends_on_id":"EV-185","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
111
+ {"id":"EV-193","title":"Add cross-run comparison to HTML report","description":"Extend the HTML reporter to optionally include comparison data from a baseline session, highlighting regressions (newly survived mutations) in red.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:49.187589087+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T08:59:14.618812927+07:00","dependencies":[{"issue_id":"EV-193","depends_on_id":"EV-185","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
112
112
  {"id":"EV-194","title":"Epic: Class and module definition mutations","description":"Add mutations for class definitions, module definitions, inheritance changes, and singleton classes. Mutant mutates these; they test structural code organization.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:20:53.918581132+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:20:53.918581132+07:00"}
113
113
  {"id":"EV-195","title":"Implement superclass removal mutation","description":"Mutate class Foo < Bar to class Foo (remove inheritance). Tests whether the superclass is actually needed. Prism class_node with superclass.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:02.559769802+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T00:16:40.526192467+07:00","dependencies":[{"issue_id":"EV-195","depends_on_id":"EV-194","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
114
- {"id":"EV-196","title":"Show code diffs for survived mutations in text output","description":"Show the exact code diff (original vs mutated) for each survived mutation in the text reporter output, similar to how Mutant displays survived mutants. Currently Evilution shows the mutation description but not the visual diff. This was specifically requested in comparison testing feedback as it helps users quickly understand what test is missing.","status":"open","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:02.574157928+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:21:02.574157928+07:00"}
114
+ {"id":"EV-196","title":"Show code diffs for survived mutations in text output","description":"Show the exact code diff (original vs mutated) for each survived mutation in the text reporter output, similar to how Mutant displays survived mutants. Currently Evilution shows the mutation description but not the visual diff. This was specifically requested in comparison testing feedback as it helps users quickly understand what test is missing.","status":"in_progress","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:02.574157928+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T11:00:52.543373742+07:00"}
115
115
  {"id":"EV-197","title":"Implement module include/extend removal","description":"Mutate include/extend/prepend statements: remove each one individually. Tests whether the mixin is actually used.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:13.978482592+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T23:57:39.685072781+07:00","dependencies":[{"issue_id":"EV-197","depends_on_id":"EV-194","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
116
116
  {"id":"EV-198","title":"Add RSpec suggestion templates for class/module mutations","description":"Add concrete suggestion templates for survived class/module mutations.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:23.284834592+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T23:47:56.899533924+07:00","dependencies":[{"issue_id":"EV-198","depends_on_id":"EV-194","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
117
- {"id":"EV-199","title":"Implement keyword argument mutations","description":"Add mutations for keyword arguments and optional keyword argument defaults. Mutations: remove keyword arg default value, swap keyword arg with positional, remove optional keyword. Prism keyword_hash_node, keyword_rest_parameter_node.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:33.74262984+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:21:33.74262984+07:00"}
117
+ {"id":"EV-199","title":"Implement keyword argument mutations","description":"Add mutations for keyword arguments and optional keyword argument defaults. Mutations: remove keyword arg default value, swap keyword arg with positional, remove optional keyword. Prism keyword_hash_node, keyword_rest_parameter_node.","status":"in_progress","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:33.74262984+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T11:08:55.837650562+07:00"}
118
118
  {"id":"EV-2","title":"Phase 1: Foundation — End-to-End Single Mutation","description":"Build the core pipeline: parse Ruby with Prism, generate mutations, fork-based isolation, RSpec integration, JSON reporting. Milestone: Runner.new(files: ['lib/user.rb']).call produces JSON output.","status":"closed","priority":2,"issue_type":"epic","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-02T00:04:58.737191467+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-02T11:02:00.342745637+07:00","closed_at":"2026-03-02T11:02:00.342745637+07:00","close_reason":"Phase 1 Foundation complete: Config, AST::Parser, Subject, SourceSurgeon, Mutation, Mutator::Base+Registry, ComparisonReplacement, Isolation::Fork, Integration::RSpec, Result objects, Reporter::JSON, Runner — all 13 tasks done"}
119
119
  {"id":"EV-2.1","title":"Implement Evilution::Config","description":"Immutable configuration value object. Fields: target_files, jobs (default: Etc.nprocessors), timeout (default: 10s), format (:json/:text), diff_base (nil), min_score (0.0), integration (:rspec), config_file path. Merge from defaults + YAML + CLI flags. File: lib/evilution/config.rb + spec.","status":"closed","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-02T00:05:50.275297792+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-02T10:43:14.688620834+07:00","closed_at":"2026-03-02T10:43:14.688620834+07:00","close_reason":"Closed","dependencies":[{"issue_id":"EV-2.1","depends_on_id":"EV-2","type":"parent-child","created_at":"0001-01-01T00:00:00Z"}]}
120
120
  {"id":"EV-2.10","title":"Implement Evilution::Integration::Base and RSpec adapter","description":"Base: abstract adapter with interface #call(test_files) -> {passed: bool, example_count: int, failure_count: int}. RSpec: programmatic runner using RSpec::Core::Runner.run with StringIO for capture. Auto-detects spec/ directory. Files: lib/evilution/integration/base.rb, lib/evilution/integration/rspec.rb + specs.","status":"closed","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-02T00:05:51.246990324+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-02T10:58:18.324768622+07:00","closed_at":"2026-03-02T10:58:18.324768622+07:00","close_reason":"Integration::Base and Integration::RSpec implemented with 8 passing specs","dependencies":[{"issue_id":"EV-2.10","depends_on_id":"EV-2","type":"parent-child","created_at":"0001-01-01T00:00:00Z"}]}
@@ -130,9 +130,9 @@
130
130
  {"id":"EV-2.8","title":"Implement Evilution::Result::MutationResult and Summary","description":"MutationResult: value object with fields: mutation, status (:killed/:survived/:timeout/:error), duration, killing_test (optional). Summary: aggregates MutationResult array into total/killed/survived/timed_out/errors/score/duration. Files: lib/evilution/result/mutation_result.rb, lib/evilution/result/summary.rb + specs.","status":"closed","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-02T00:05:51.022249568+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-02T10:51:08.482621898+07:00","closed_at":"2026-03-02T10:51:08.482621898+07:00","close_reason":"Closed","dependencies":[{"issue_id":"EV-2.8","depends_on_id":"EV-2","type":"parent-child","created_at":"0001-01-01T00:00:00Z"}]}
131
131
  {"id":"EV-2.9","title":"Implement Evilution::Isolation::Fork","description":"Fork-based process isolation. Method: run(mutation, test_command, timeout:) -> MutationResult. Flow: create pipe, fork child, child applies mutation via eval, child runs test command, marshal result back via pipe, parent reads with IO.select timeout, SIGKILL on deadline. File: lib/evilution/isolation/fork.rb + spec.","status":"closed","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-02T00:05:51.142167275+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-02T10:54:08.819310594+07:00","closed_at":"2026-03-02T10:54:08.819310594+07:00","close_reason":"Fork isolation implemented with 6 passing specs","dependencies":[{"issue_id":"EV-2.9","depends_on_id":"EV-2","type":"parent-child","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"EV-2.9","depends_on_id":"EV-2.8","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
132
132
  {"id":"EV-20","title":"Deprecate coverage filtering","description":"With line-range and method-name targeting, coverage collection adds overhead for little benefit. Deprecate --no-coverage flag, coverage config key, and remove coverage logic from runner.","status":"closed","priority":2,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-10T00:30:58.837659684+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-10T00:33:06.453669976+07:00","closed_at":"2026-03-10T00:33:06.453669976+07:00","close_reason":"Deprecated coverage filtering: CLI warns on --no-coverage, config warns on coverage key, runner no longer uses coverage logic"}
133
- {"id":"EV-200","title":"Implement multiple assignment (masgn) mutations","description":"Add mutations for destructuring/parallel assignment (a, b = 1, 2). Mutations: remove individual assignment targets, swap assignment order, reduce to single assignment. Prism multi_write_node.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:44.259585319+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:21:44.259585319+07:00"}
134
- {"id":"EV-201","title":"Implement yield statement mutations","description":"Add mutations for yield statements. Mutations: remove yield, remove yield arguments, replace yield value with nil. Prism yield_node.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:53.437749245+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:21:53.437749245+07:00"}
135
- {"id":"EV-202","title":"Implement splat operator mutations","description":"Add mutations for splat (*) and double-splat (**) operators. Mutations: remove splat (pass array directly), remove double-splat (pass hash directly). Prism splat_node, assoc_splat_node.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:22:01.958187896+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:22:01.958187896+07:00"}
133
+ {"id":"EV-200","title":"Implement multiple assignment (masgn) mutations","description":"Add mutations for destructuring/parallel assignment (a, b = 1, 2). Mutations: remove individual assignment targets, swap assignment order, reduce to single assignment. Prism multi_write_node.","status":"in_progress","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:44.259585319+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T11:36:39.551815499+07:00"}
134
+ {"id":"EV-201","title":"Implement yield statement mutations","description":"Add mutations for yield statements. Mutations: remove yield, remove yield arguments, replace yield value with nil. Prism yield_node.","status":"in_progress","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:21:53.437749245+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T11:47:36.054086735+07:00"}
135
+ {"id":"EV-202","title":"Implement splat operator mutations","description":"Add mutations for splat (*) and double-splat (**) operators. Mutations: remove splat (pass array directly), remove double-splat (pass hash directly). Prism splat_node, assoc_splat_node.","status":"in_progress","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:22:01.958187896+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T12:15:56.890122869+07:00"}
136
136
  {"id":"EV-203","title":"Epic: Extended equivalent mutation detection","description":"Extend equivalent mutation detection with more heuristics and manual marking support. Evilution's equivalent detection is already praised in feedback; extending it further strengthens a competitive advantage.","status":"open","priority":3,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:22:11.400012571+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:22:11.400012571+07:00"}
137
137
  {"id":"EV-204","title":"Add more automatic equivalence heuristics","description":"Add new equivalence detection strategies: frozen string mutations (frozen strings are immutable, mutation is equivalent), private method rename (if only called internally with same signature), constant folding equivalences.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:22:20.07787144+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T21:21:19.35465527+07:00","dependencies":[{"issue_id":"EV-204","depends_on_id":"EV-203","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
138
138
  {"id":"EV-205","title":"Support # evilution:equivalent manual marking","description":"Allow users to mark specific mutations as equivalent using source comments: # evilution:equivalent. These should be excluded from the score denominator like auto-detected equivalents.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:22:31.543822152+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T22:08:20.967272294+07:00","dependencies":[{"issue_id":"EV-205","depends_on_id":"EV-203","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
@@ -141,9 +141,10 @@
141
141
  {"id":"EV-208","title":"Add cross-run diff to MCP server","description":"Add MCP tool for comparing two sessions and returning the diff. Enables AI agents to detect regressions.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:00.558002099+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T10:58:31.301603302+07:00","dependencies":[{"issue_id":"EV-208","depends_on_id":"EV-206","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
142
142
  {"id":"EV-209","title":"Add streaming test suggestions via MCP","description":"Stream test suggestions for survived mutations via MCP as they are generated, rather than waiting for the full run to complete.","status":"in_progress","priority":3,"issue_type":"task","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:10.316219498+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-28T11:10:26.677490317+07:00","dependencies":[{"issue_id":"EV-209","depends_on_id":"EV-206","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
143
143
  {"id":"EV-21","title":"Epic: Speed & Performance","description":"Reduce mutation testing wall-clock time for fast agent feedback loops. Includes fail-fast, parallel execution, and per-mutation spec targeting.","status":"closed","priority":1,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-10T06:17:26.608316104+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-16T14:49:23.063583958+07:00","closed_at":"2026-03-16T14:49:23.063583958+07:00","close_reason":"All children complete: fail-fast, per-mutation spec targeting","dependencies":[{"issue_id":"EV-21","depends_on_id":"EV-22","type":"blocks","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"EV-21","depends_on_id":"EV-23","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
144
- {"id":"EV-210","title":"Implement defined? check mutations","description":"Add mutation for defined?(expr) → true. Tests whether the defined? check is actually needed. Prism defined_node.","status":"open","priority":4,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:22.128405637+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:23:22.128405637+07:00"}
145
- {"id":"EV-211","title":"Implement regex capture reference (, ) mutations","description":"Add mutations for numbered regex capture references ($1, $2, etc.). Mutations: swap capture numbers ($1↔$2), replace with nil. Prism numbered_reference_read_node.","status":"open","priority":4,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:30.659728763+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:23:30.659728763+07:00"}
146
- {"id":"EV-212","title":"Implement self reference mutations","description":"Add mutations for self references. Mutations: remove self where it's used as an explicit receiver (self.foo → foo). Prism self_node.","status":"open","priority":4,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:42.173027795+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-23T11:23:42.173027795+07:00"}
144
+ {"id":"EV-210","title":"Implement defined? check mutations","description":"Add mutation for defined?(expr) → true. Tests whether the defined? check is actually needed. Prism defined_node.","status":"in_progress","priority":4,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:22.128405637+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T12:41:21.72963442+07:00"}
145
+ {"id":"EV-211","title":"Implement regex capture reference (, ) mutations","description":"Add mutations for numbered regex capture references ($1, $2, etc.). Mutations: swap capture numbers ($1↔$2), replace with nil. Prism numbered_reference_read_node.","status":"in_progress","priority":4,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:30.659728763+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-03T12:58:30.17449728+07:00"}
146
+ {"id":"EV-212","title":"Implement self reference mutations","description":"Add mutations for self references. Mutations: remove self where it's used as an explicit receiver (self.foo → foo). Prism self_node.","status":"closed","priority":4,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-23T11:23:42.173027795+07:00","created_by":"Denis Kiselev","updated_at":"2026-04-02T11:58:04.342971748+07:00","closed_at":"2026-04-02T11:58:04.342971748+07:00","close_reason":"Already implemented by ReceiverReplacement operator (self.foo → foo)"}
147
+ {"id":"EV-213","title":"Critical: SourceSurgeon crashes on multi-byte UTF-8 source files","description":"SourceSurgeon.apply uses String#[]= with Prism byte offsets, but Ruby String#[]= interprets indices as character offsets for UTF-8 strings. This causes IndexError on files containing multi-byte characters (e.g. Cyrillic, CJK, emoji). Fix: use source.b to force ASCII-8BIT before byte-offset operations, or use byteslice-based replacement. Reported by end user on 2026-03-29 against v0.16.0.","status":"open","priority":0,"issue_type":"bug","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-29T23:19:47.803570297+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-29T23:19:47.803570297+07:00"}
147
148
  {"id":"EV-22","title":"Add --fail-fast flag with survivor threshold","description":"Add --fail-fast [N] CLI flag and fail_fast config option to stop mutation testing after N surviving mutants (default N=1 when flag given without value). Agents fix gaps iteratively, so discovering all survivors upfront is wasted work. A threshold gives control over the speed/thoroughness tradeoff: --fail-fast 1 for quick checks, --fail-fast 5 for CI gates, omit for full scans. Runner#call should stop running mutations and return a partial Summary once the threshold is reached. JSON output should include a 'truncated: true' field when fail-fast triggered.","status":"closed","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-10T06:17:28.018733235+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-16T10:11:01.311500554+07:00","closed_at":"2026-03-16T10:11:01.311500554+07:00","close_reason":"Already merged and released in v0.4.0"}
148
149
  {"id":"EV-23","title":"Per-mutation spec targeting","description":"Instead of running the full spec suite for every mutation, map each mutated source file to its relevant spec file(s) using convention-based resolution (e.g. lib/foo/bar.rb -> spec/foo/bar_spec.rb) and only run those. This dramatically reduces per-mutation test time. Depends on convention-based spec file resolution being implemented first.","status":"closed","priority":2,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-10T06:17:28.98620973+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-16T14:49:13.616876819+07:00","closed_at":"2026-03-16T14:49:13.616876819+07:00","close_reason":"Fixed and merged","dependencies":[{"issue_id":"EV-23","depends_on_id":"EV-34","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
149
150
  {"id":"EV-24","title":"Epic: JSON Output Improvements","description":"Make JSON output fully machine-parseable in all scenarios, including errors. Add diagnostic fields that help agents debug failures.","status":"closed","priority":1,"issue_type":"feature","owner":"denis.kiselyov@gmail.com","created_at":"2026-03-10T06:17:37.450686472+07:00","created_by":"Denis Kiselev","updated_at":"2026-03-16T11:15:24.900944562+07:00","closed_at":"2026-03-16T11:15:24.900944562+07:00","close_reason":"All children complete: structured errors, test_command in JSON, noise suppression","dependencies":[{"issue_id":"EV-24","depends_on_id":"EV-25","type":"blocks","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"EV-24","depends_on_id":"EV-26","type":"blocks","created_at":"0001-01-01T00:00:00Z"},{"issue_id":"EV-24","depends_on_id":"EV-40","type":"blocks","created_at":"0001-01-01T00:00:00Z"}]}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,53 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.18.0] - 2026-04-03
4
+
5
+ ### Added
6
+
7
+ - **Disable comments** — `# evilution:disable` comments to suppress mutations on specific lines, methods, or regions; inline disable for single lines, standalone disable before `def` for entire methods, range disable/enable pairs for arbitrary regions; `--show-disabled` flag reports skipped mutations in CLI, JSON, and HTML output (#321, #323, #325)
8
+ - **Sorbet `sig` filtering** — automatically detects and excludes mutations inside Sorbet `sig { ... }` blocks; cached per file for performance (#330, #334)
9
+ - **Session diff engine** — `Evilution::Session::Diff` compares two saved sessions, reporting fixed mutations, new survivors, persistent survivors, and score delta; identity matching by `[operator, file, line, subject]` (#333)
10
+ - **`session diff` CLI command** — `evilution session diff <base> <head>` with color-coded text output (green=fixed, red=new survivors, yellow=persistent) and `--format json` support (#336)
11
+ - **HTML report baseline comparison** — `--baseline-session PATH` overlays a saved session on the HTML report, highlighting regressions with badges and showing score delta (#339)
12
+ - **`util mutation` CLI command** — `evilution util mutation [-e CODE | FILE]` previews all mutations for a source file or inline Ruby snippet; supports `--format json` (#328)
13
+ - **`subjects` CLI command** — `evilution subjects [files...]` lists all mutation subjects (methods) with file locations and mutation counts; supports `--stdin` (#322)
14
+ - **`tests list` CLI command** — `evilution tests list [files...]` lists spec files mapped to source files via `SpecResolver` (#326)
15
+ - **`environment show` CLI command** — `evilution environment show` displays runtime environment: version, Ruby version, config path, and all active settings (#319)
16
+ - **Type-aware return mutation operators** — `CollectionReturn` replaces collection return values with type-aware alternatives (`[]`, `{}`); `ScalarReturn` replaces scalar return values with type-aware alternatives (`0`, `""`, `nil`) (#300, #304)
17
+ - **Keyword argument mutations** — `KeywordArgument` operator removes default values, removes optional keywords entirely, and removes `**kwargs` rest parameters (#345)
18
+ - **Multiple assignment mutations** — `MultipleAssignment` operator removes individual assignment targets and swaps 2-element order (#346)
19
+ - **Yield statement mutations** — `YieldStatement` operator removes yield, removes yield arguments, and replaces yield value with `nil` (#347)
20
+ - **Splat operator mutations** — `SplatOperator` operator removes `*` (splat) and `**` (double-splat) from method calls and array literals (#348)
21
+ - **`defined?` check mutations** — `DefinedCheck` operator replaces `defined?(expr)` with `true` (#356)
22
+ - **Regex capture reference mutations** — `RegexCapture` operator swaps numbered capture references (`$1`↔`$2`) and replaces with `nil` (#357)
23
+ - **Suggestion templates** — concrete RSpec suggestions for `collection_return` and `scalar_return` operators (#308)
24
+ - **Efficiency metrics** — summary output includes `efficiency` (killtime/wall-clock ratio), `mutations_per_second` throughput, and `killtime` aggregate; reported in CLI, JSON, and HTML (#313)
25
+ - **Parallel execution metrics** — worker statistics tracking with `busy_time`, `wall_time`, `idle_time`, and `utilization` per worker (#314)
26
+ - **Demand-driven work distribution** — `Parallel::Pool` uses pipe-based shared work queue with demand-driven dispatch and configurable prefetch; replaces batch-based distribution (#303, #307, #311)
27
+
28
+ ### Changed
29
+
30
+ - **Operator count** — 60 operators (up from 52), with new return-type, keyword, assignment, yield, splat, defined?, and regex capture operators
31
+ - **CLI reporter** — survived mutations now include subject name and code diffs (#341)
32
+ - **Dependency updates** — Ruby 3.3.10 → 3.3.11 in CI (#447), ruby/setup-ruby 1.295.0 → 1.299.0, rubygems/release-gem 1.1.4 → 1.2.0
33
+
34
+ ## [0.17.0] - 2026-03-30
35
+
36
+ ### Added
37
+
38
+ - **Hooks system** — lifecycle hooks for mutation testing pipeline: `worker_process_start` for parallel workers, `mutation_insert_pre`/`post` for RSpec integration, `setup_integration_pre`/`post` for test setup; hook registry with registration, dispatch, and error isolation; `.evilution.yml` hooks configuration (#265, #272, #277, #282, #286, #290)
39
+ - **Index access mutation operators** — `IndexToFetch` replaces `[]` with `.fetch()`, `IndexToDig` replaces `[]` chains with `.dig()`, `IndexAssignmentRemoval` removes `[]=` assignments (#280, #283, #288)
40
+ - **Pattern matching mutation operators** — `PatternMatchingGuard` removes or negates guard clauses in `case/in` patterns; `PatternMatchingAlternative` removes, reorders alternatives in `pat1 | pat2` patterns; `PatternMatchingArray` removes or wildcards elements in array and find patterns (#293, #297, #301)
41
+ - **AST pattern language** — custom DSL for `ignore_patterns` configuration: node type matching, attribute constraints, nested patterns, wildcards (`_`, `*`, `**`), negation, and alternatives; recursive descent parser producing matcher objects; syntax spec in `docs/ast_pattern_syntax.md` (#312, #315)
42
+ - **AST pattern filter integration** — mutations matching `ignore_patterns` are skipped during generation; skipped count reported in CLI, JSON, HTML reporters and session data (#317)
43
+ - **`ignore_patterns` config** — new `.evilution.yml` key accepting an array of AST pattern strings to exclude mutations on logging/debug/infrastructure code (#320)
44
+ - **Suggestion templates** — concrete RSpec suggestions for index access mutations (`index_to_fetch`, `index_to_dig`, `index_assignment_removal`) and pattern matching mutations (`pattern_matching_guard`, `pattern_matching_alternative`, `pattern_matching_array`) (#292, #305)
45
+
46
+ ### Changed
47
+
48
+ - **Operator count** — 52 operators (up from 46), with new index access, pattern matching, and hooks integration
49
+ - **Hooks wiring** — Runner passes hooks through to Fork isolator, RSpec integration, and Parallel::Pool; comprehensive test coverage for hooks lifecycle (#295)
50
+
3
51
  ## [0.16.1] - 2026-03-30
4
52
 
5
53
  ### Fixed