mlrepromutate 0.1.1__tar.gz

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.
@@ -0,0 +1,29 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+
8
+ # Virtual environments
9
+ .venv/
10
+ venv/
11
+
12
+ # Testing
13
+ .pytest_cache/
14
+ .coverage
15
+ htmlcov/
16
+
17
+ # Ruff
18
+ .ruff_cache/
19
+
20
+ # IDE
21
+ .vscode/
22
+ .idea/
23
+
24
+ # OS
25
+ .DS_Store
26
+
27
+ # Temporary experiment data
28
+ .tmp/
29
+ tmp/
@@ -0,0 +1,82 @@
1
+ # Changelog
2
+
3
+ All notable changes to MLReproMutate will be documented in this file.
4
+
5
+ MLReproMutate is currently pre-1.0 software; its public API may change between
6
+ releases.
7
+
8
+ ## [0.1.1] - 2026-08-28
9
+
10
+ ### Fixed
11
+
12
+ - Report the installed MLReproMutate package version from distribution
13
+ metadata instead of a hard-coded development placeholder.
14
+ - Resolve validation commands using either `python` or `python3` when one of
15
+ those common executable aliases is unavailable.
16
+
17
+ ### Added
18
+
19
+ - Interactive command-line setup for guided project, operator, validation,
20
+ execution-mode, and candidate selection.
21
+ - Static `detect` command for previewing mutation candidates without executing
22
+ project code.
23
+ - `in-place` execution mode for disposable, CI, container, or otherwise safely
24
+ resettable workspaces.
25
+ - Repeatable project-relative `--exclude` options for omitting unnecessary
26
+ paths from sandbox copies.
27
+ - User-facing quick-start and command-line documentation.
28
+ - CI usage documentation for reproducibility mutation checks.
29
+ - Expanded worked examples for the supported mutation operators.
30
+ - Public citation and link for the accompanying empirical study,
31
+ arXiv:2608.27100.
32
+ - GitHub Actions workflow for PyPI Trusted Publishing.
33
+
34
+ ### Changed
35
+
36
+ - Require explicit selection of a mutation operator instead of defaulting to
37
+ `dependency-pin`.
38
+ - Keep `sandbox` as the safe default execution mode while allowing users to
39
+ avoid full project copies with explicit `in-place` execution.
40
+ - Expanded installation, usage, interpretation, isolation, and contribution
41
+ guidance.
42
+
43
+
44
+ ## [0.1.0] - 2026-08-27
45
+ ### Changed
46
+
47
+ - Reuse a successful baseline validation across all mutation candidates in a single orchestration run.
48
+
49
+ ### Added
50
+
51
+ - Initial public repository structure.
52
+ - Initial project scope and research question.
53
+ - Initial threat-model documentation.
54
+ - Continuous integration setup.
55
+ - Core mutation outcome, candidate, and result models.
56
+ - Base interface for reproducibility mutation operators.
57
+ - Isolated temporary project sandbox for safe mutation execution.
58
+ - Experiment command runner with captured output, exit status, runtime, and timeout handling.
59
+ - Dependency mutation operator for relaxing exact pins in requirements files.
60
+ - Mutation evaluation pipeline with baseline validation and KILLED, SURVIVED, and TIMEOUT classification.
61
+ - End-to-end dependency mutation fixture demonstrating both surviving and killed reproducibility mutations.
62
+ - Mutation orchestration layer for detecting and evaluating operator candidates.
63
+ - Initial `mlrepromutate run` command for end-to-end dependency mutation evaluation.
64
+ - Added incremental CLI progress reporting for baseline validation and individual mutation evaluation.
65
+ - Added workflow-aware dependency mutation scoping through `--requirements-file`.
66
+ - Mutation progress output now includes the source file and line number.
67
+ - Added machine-readable JSON reports containing validation provenance,
68
+ mutation metadata, outcomes, execution durations, and Git revisions.
69
+ - Added an isolated virtual-environment resolver foundation for future
70
+ dependency re-resolution experiments.
71
+ - Added resolved dependency evaluation with explicit `INVALID`,
72
+ `EQUIVALENT`, `SURVIVED`, `KILLED`, and `TIMEOUT` semantics.
73
+ - Added a controlled offline resolved-dependency fixture demonstrating a real
74
+ dependency transition from version 1.0.0 to 1.1.0.
75
+ - Added AST-based detection and mutation of literal Python random seeds for
76
+ `random.seed`, NumPy seed calls, and `torch.manual_seed`.
77
+ - Added a controlled random-seed fixture demonstrating both survived and
78
+ killed reproducibility mutations.
79
+ - Added the `data-split` mutation operator for removing explicit
80
+ `train_test_split` stratification.
81
+ - Added the `cv-fold-count` mutation operator for changing explicit
82
+ cross-validation fold counts.
@@ -0,0 +1,18 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use MLReproMutate in research, please cite this software."
3
+ type: software
4
+ title: "MLReproMutate"
5
+ authors:
6
+ - family-names: "Shulepov"
7
+ given-names: "Ilya"
8
+ orcid: "https://orcid.org/0009-0001-1348-9576"
9
+ version: 0.1.1
10
+ date-released: 2026-08-28
11
+ repository-code: "https://github.com/ilyuka/MLReproMutate"
12
+ url: "https://github.com/ilyuka/MLReproMutate"
13
+ license: MIT
14
+ keywords:
15
+ - mutation testing
16
+ - reproducibility
17
+ - machine learning
18
+ - research software
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ilya Shulepov
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,413 @@
1
+ Metadata-Version: 2.5
2
+ Name: mlrepromutate
3
+ Version: 0.1.1
4
+ Summary: Mutation testing for reproducibility safeguards in machine-learning experiments
5
+ Project-URL: Homepage, https://github.com/ilyuka/MLReproMutate
6
+ Project-URL: Repository, https://github.com/ilyuka/MLReproMutate
7
+ Project-URL: Issues, https://github.com/ilyuka/MLReproMutate/issues
8
+ Project-URL: Documentation, https://github.com/ilyuka/MLReproMutate/tree/main/docs
9
+ Project-URL: Changelog, https://github.com/ilyuka/MLReproMutate/blob/main/CHANGELOG.md
10
+ Project-URL: Preprint, https://arxiv.org/abs/2608.27100
11
+ Author: Ilya Shulepov
12
+ License: MIT
13
+ License-File: LICENSE
14
+ Keywords: machine learning,mutation testing,reproducibility,research software
15
+ Classifier: Development Status :: 3 - Alpha
16
+ Classifier: Intended Audience :: Developers
17
+ Classifier: Intended Audience :: Science/Research
18
+ Classifier: License :: OSI Approved :: MIT License
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Programming Language :: Python :: 3
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
25
+ Classifier: Topic :: Software Development :: Testing
26
+ Requires-Python: >=3.11
27
+ Requires-Dist: typer>=0.12
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest-cov>=5; extra == 'dev'
30
+ Requires-Dist: pytest>=8; extra == 'dev'
31
+ Requires-Dist: ruff>=0.6; extra == 'dev'
32
+ Description-Content-Type: text/markdown
33
+
34
+ # MLReproMutate
35
+
36
+ MLReproMutate is research software for mutation testing of
37
+ reproducibility-relevant safeguards in machine-learning research software.
38
+
39
+ It introduces controlled changes to experimental and environment choices and
40
+ evaluates whether validation workflows already present in a repository detect
41
+ those changes.
42
+
43
+ MLReproMutate is intended for empirical software-engineering research,
44
+ machine-learning reproducibility studies, and developers who want to assess
45
+ whether existing validation workflows constrain reproducibility-relevant
46
+ experimental choices.
47
+
48
+ ## Installation
49
+
50
+ MLReproMutate requires Python 3.11 or newer.
51
+
52
+ Clone the repository and install the package:
53
+
54
+ ```bash
55
+ git clone https://github.com/ilyuka/MLReproMutate.git
56
+ cd MLReproMutate
57
+
58
+ python -m venv .venv
59
+ source .venv/bin/activate
60
+
61
+ python -m pip install .
62
+ ```
63
+
64
+ Confirm the installation:
65
+
66
+ ```bash
67
+ mlrepromutate version
68
+ mlrepromutate --help
69
+ ```
70
+
71
+ For a guided first run, start the interactive setup:
72
+
73
+ ```bash
74
+ mlrepromutate
75
+ ```
76
+
77
+ The wizard guides you through project selection, mutation operator,
78
+ validation command, execution mode, candidate preview, and confirmation.
79
+
80
+ For development dependencies:
81
+
82
+ ```bash
83
+ python -m pip install -e ".[dev]"
84
+ ```
85
+
86
+ ## Quick start
87
+
88
+ The repository includes small CPU-runnable fixtures demonstrating the mutation
89
+ workflow.
90
+
91
+ The `random-seed` fixture can be run without additional machine-learning
92
+ dependencies:
93
+
94
+ ```bash
95
+ mlrepromutate run examples/random-seed \
96
+ --command "python validate_unguarded.py" \
97
+ --operator random-seed \
98
+ --python-file experiment.py
99
+ ```
100
+
101
+ MLReproMutate first validates the unmodified baseline. It then detects the
102
+ supported mutation candidate, applies the mutation in the selected execution
103
+ workspace, runs the same validation command, and reports whether the workflow
104
+ detected the change. The default `sandbox` execution mode uses temporary
105
+ isolated project copies.
106
+
107
+ For the unguarded fixture, the random-seed mutation survives because the
108
+ validation workflow checks only that the experiment completes successfully.
109
+
110
+ The same mutation can be evaluated against a workflow containing an explicit
111
+ reproducibility safeguard:
112
+
113
+ ```bash
114
+ mlrepromutate run examples/random-seed \
115
+ --command "python validate_guarded.py" \
116
+ --operator random-seed \
117
+ --python-file experiment.py
118
+ ```
119
+
120
+ For this fixture, the mutation is killed because the guarded workflow checks the
121
+ deterministic output associated with the original seed.
122
+
123
+ See the [quick-start guide](docs/quickstart.md) for the complete walkthrough.
124
+
125
+ ## Mutation operators
126
+
127
+ The current release implements four reproducibility-relevant mutation classes.
128
+
129
+ ### `random-seed`
130
+
131
+ Changes a supported literal random seed from `N` to `N + 1`.
132
+
133
+ Supported seed-setting forms include calls such as:
134
+
135
+ ```python
136
+ random.seed(42)
137
+ np.random.seed(42)
138
+ numpy.random.seed(42)
139
+ torch.manual_seed(42)
140
+ ```
141
+
142
+ ### `dependency-pin`
143
+
144
+ Relaxes an exact dependency constraint:
145
+
146
+ ```text
147
+ package==version
148
+ ```
149
+
150
+ to:
151
+
152
+ ```text
153
+ package>=version
154
+ ```
155
+
156
+ The resolved-dependency evaluation mode can additionally determine whether the
157
+ changed specification actually resolves to a different installed version of the
158
+ target dependency.
159
+
160
+ ### `data-split`
161
+
162
+ Changes a supported `train_test_split` call containing an explicit non-`None`
163
+ `stratify` argument:
164
+
165
+ ```python
166
+ stratify=<expression>
167
+ ```
168
+
169
+ to:
170
+
171
+ ```python
172
+ stratify=None
173
+ ```
174
+
175
+ ### `cv-fold-count`
176
+
177
+ Changes an explicit literal cross-validation fold count from `N` to `N + 1`.
178
+
179
+ Supported splitter classes include `KFold`, `StratifiedKFold`,
180
+ `RepeatedKFold`, and `RepeatedStratifiedKFold`.
181
+
182
+ ## Evaluation model
183
+
184
+ Mutation evaluation is baseline-first.
185
+
186
+ The unmodified project is evaluated before any mutation outcome is interpreted.
187
+ A baseline failure or timeout is therefore kept separate from a mutation
188
+ result.
189
+
190
+ After a successful baseline, selected mutations are evaluated in isolated
191
+ project workspaces using the same validation command.
192
+
193
+ At the execution level:
194
+
195
+ - `KILLED` means that the selected validation workflow returned a non-zero
196
+ status after the mutation was applied.
197
+ - `SURVIVED` means that the selected validation workflow completed successfully
198
+ after the mutation was applied.
199
+ - baseline failures and validation timeouts are represented separately.
200
+ - additional semantic states are used where necessary, including dependency
201
+ equivalence handling during resolved evaluation.
202
+
203
+ A survived mutation does **not** by itself establish that a repository or its
204
+ scientific results are irreproducible. It shows only that the selected
205
+ validation workflow did not detect that particular controlled change.
206
+
207
+ ## Candidate preview
208
+
209
+ Mutation candidates can be inspected without executing project code:
210
+
211
+ ```bash
212
+ mlrepromutate detect examples/random-seed \
213
+ --operator random-seed \
214
+ --python-file experiment.py
215
+ ```
216
+
217
+ `detect` performs candidate detection only. It does not run the baseline,
218
+ validation command, or mutants.
219
+
220
+ ## Execution modes
221
+
222
+ The default `sandbox` mode evaluates the project in temporary copies so that
223
+ mutation targets in the original project are not modified:
224
+
225
+ ```bash
226
+ mlrepromutate run PROJECT \
227
+ --operator random-seed \
228
+ --command "pytest -q" \
229
+ --execution-mode sandbox
230
+ ```
231
+
232
+ Large directories that are not needed by the validation workflow can be omitted
233
+ from sandbox copies with repeatable project-relative `--exclude` options:
234
+
235
+ ```bash
236
+ mlrepromutate run PROJECT \
237
+ --operator random-seed \
238
+ --command "pytest -q" \
239
+ --execution-mode sandbox \
240
+ --exclude data \
241
+ --exclude checkpoints
242
+ ```
243
+
244
+ Exclusion paths are interpreted relative to the project root. Absolute paths
245
+ and parent-directory traversal are rejected.
246
+
247
+ The `in-place` mode avoids copying the project and is intended for disposable
248
+ or version-controlled workspaces such as CI checkouts:
249
+
250
+ ```bash
251
+ mlrepromutate run PROJECT \
252
+ --operator random-seed \
253
+ --command "pytest -q" \
254
+ --execution-mode in-place
255
+ ```
256
+
257
+ MLReproMutate restores its mutation target after each in-place evaluation,
258
+ including failed or timed-out validations. However, arbitrary side effects
259
+ created by the validation command itself are not reverted. For that reason,
260
+ `in-place` should be used only in workspaces where such side effects are safe.
261
+
262
+ `dependency-pin --dependency-mode resolved` currently requires `sandbox` mode.
263
+
264
+ ## Continuous integration
265
+
266
+ MLReproMutate can be used as a CI validation step. A disposable CI checkout is
267
+ a natural fit for `in-place` execution because no full project copy is needed:
268
+
269
+ ```yaml
270
+ - uses: actions/checkout@v4
271
+
272
+ - name: Install MLReproMutate
273
+ run: python3 -m pip install mlrepromutate
274
+
275
+ - name: Check reproducibility safeguards
276
+ run: |
277
+ mlrepromutate run . \
278
+ --operator random-seed \
279
+ --python-file experiment.py \
280
+ --execution-mode in-place \
281
+ --command "pytest -q"
282
+ ```
283
+
284
+ For human use, `mlrepromutate` provides an interactive setup. For scripts, CI,
285
+ and reproducible research workflows, prefer explicit `detect` and `run`
286
+ commands.
287
+
288
+ ## Python validation commands
289
+
290
+ For validation commands whose executable is exactly `python` or `python3`,
291
+ MLReproMutate resolves the requested executable from `PATH` and falls back to
292
+ the other common alias when necessary. Other executables such as `pytest`,
293
+ `bash`, and `make` are not rewritten.
294
+
295
+ ## Machine-readable reports
296
+
297
+ Use `--json-out` to write a structured report:
298
+
299
+ ```bash
300
+ mlrepromutate run examples/random-seed \
301
+ --command "python validate_unguarded.py" \
302
+ --operator random-seed \
303
+ --python-file experiment.py \
304
+ --json-out report.json
305
+ ```
306
+
307
+ Reports contain software and project metadata, validation information, mutation
308
+ candidate metadata, outcomes, and execution details.
309
+
310
+ ## Documentation
311
+
312
+ User documentation:
313
+
314
+ - [Quick start](docs/quickstart.md)
315
+ - [Command-line interface](docs/cli.md)
316
+ - [Examples](examples/README.md)
317
+
318
+ Research and design materials:
319
+
320
+ - [Threat model](docs/threat-model.md)
321
+ - [Research log](docs/research-log.md)
322
+ - [Related-work notes](docs/related-work.md)
323
+
324
+ Command-line help for the installed version is also available with:
325
+
326
+ ```bash
327
+ mlrepromutate run --help
328
+ ```
329
+
330
+ ## Examples
331
+
332
+ The `examples/` directory contains small fixtures for exercising individual
333
+ mutation concepts and evaluation behavior.
334
+
335
+ These fixtures are separate from the frozen empirical corpus and are intended
336
+ for documentation, testing, and software evaluation.
337
+
338
+ See [examples/README.md](examples/README.md).
339
+
340
+ ## Empirical research
341
+
342
+ MLReproMutate has been used as the experimental instrument in an empirical
343
+ study of reproducibility-relevant safeguards in machine-learning research
344
+ software.
345
+
346
+ The repository contains the frozen machine-readable evidence underlying that
347
+ study, including corpus records, restoration evidence, study metadata,
348
+ generated accounting tables, and provenance information.
349
+
350
+ The empirical corpus is frozen and is not expanded or modified in response to
351
+ observed mutation outcomes.
352
+
353
+ The software release and frozen empirical artifacts are archived on Zenodo:
354
+
355
+ **MLReproMutate v0.1.0**
356
+ DOI: https://doi.org/10.5281/zenodo.22126120
357
+
358
+ The accompanying empirical study is available as a preprint:
359
+
360
+ **Ilya Shulepov. _Mutation Testing for Reproducibility Safeguards in Machine
361
+ Learning Research Software: An Empirical Study._ arXiv:2608.27100, 2026.**
362
+
363
+ https://arxiv.org/abs/2608.27100
364
+
365
+ ## Development
366
+
367
+ Install the development environment:
368
+
369
+ ```bash
370
+ python -m pip install -e ".[dev]"
371
+ ```
372
+
373
+ Run the test suite:
374
+
375
+ ```bash
376
+ python -m pytest -q
377
+ ```
378
+
379
+ Run static checks:
380
+
381
+ ```bash
382
+ ruff check src tests
383
+ ```
384
+
385
+ The continuous-integration workflow runs the software checks across supported
386
+ Python versions.
387
+
388
+ ## Reporting problems and contributing
389
+
390
+ Bug reports, usability feedback, research use cases, documentation
391
+ improvements, and suggestions for reproducibility mutation operators are
392
+ welcome.
393
+
394
+ Please use the GitHub issue tracker for reproducible bugs or usability
395
+ problems:
396
+
397
+ https://github.com/ilyuka/MLReproMutate/issues
398
+
399
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development and contribution
400
+ guidelines.
401
+
402
+ ## Citation
403
+
404
+ Citation metadata is provided in [CITATION.cff](CITATION.cff).
405
+
406
+ The archived software release can be cited using:
407
+
408
+ > Shulepov, Ilya. MLReproMutate, version 0.1.0. Zenodo, 2026.
409
+ > https://doi.org/10.5281/zenodo.22126120
410
+
411
+ ## License
412
+
413
+ MLReproMutate is released under the [MIT License](LICENSE).