Domain-agnostic mutation framework for structured artifacts
Project description
Miova
A domain-agnostic mutation framework for structured artifacts.
Miova is a Python framework for creating, executing, validating, composing and reporting mutations over structured artifacts.
It provides a domain-agnostic runtime for controlled transformations, with explicit contracts, invariant validation, immutable lineage tracking, mutation pipelines, exploration campaigns and payload-level reporting.
Miova is designed for use cases such as:
- mutation testing
- property-based testing
- intelligent fuzzing
- structured artifact exploration
- formal-methods-oriented validation
- DSL and IR robustness testing
- transformation analysis
GitHub topics:
python · framework · mutation-testing · property-based-testing · fuzzing · formal-methods · software-testing · invariants · developer-tools
Project status
Miova is currently released as v0.1.0 / V1 preview.
This means the framework is usable as a Python library and its core runtime is validated by automated tests, documentation builds, packaging checks and GitHub Actions.
The public API is intentionally structured and tested, but may still evolve before a formal 1.0.0 release.
Current guarantees:
- installable as a Python package
- importable from external projects
- covered by P0/P1/P2 test suites
- validated by GitHub Actions
- executable examples
- MkDocs documentation build
- payload-level mutation reporting
- multi-domain runtime support
Versioning intent:
0.1.0 — first usable V1 preview runtime
1.0.0 — stable public API release
Why Miova?
Modern systems manipulate increasingly complex structured artifacts:
- source code
- DSL instances
- intermediate representations
- graphs
- documents
- YAML / JSON configurations
- machine learning model descriptions
- structured datasets
Testing and exploring these artifacts often requires transformation logic tightly coupled to each domain.
Miova introduces a generic mutation architecture based on a few core concepts:
- Artifact — the universal unit manipulated by the framework
- Adapter — the bridge between Miova and a domain-specific representation
- Mutation — an executable transformation operator
- Mutation Contract — the semantic description of a mutation
- Invariant — a rule defining what must remain valid
- Pipeline — a sequence of mutations
- Campaign — automated exploration through generated pipelines
- Reporting — human-readable payload-level change reports
The goal is to separate:
- domain representation
- transformation logic
- validation rules
- execution orchestration
- reporting and observability
Core architecture
flowchart LR
A[Artifact]
--> B[Adapter]
B
--> C[Domain Object]
C
--> D[Mutation]
D
--> E[Mutated Domain Object]
E
--> F[Adapter]
F
--> G[New Artifact]
G
--> H[Invariant Engine]
H
--> I[Mutation Result]
I
--> J[Payload Report]
Miova does not assume a specific artifact type.
The same runtime can operate on different domains as long as each domain provides an adapter.
Key concepts
Artifact
An Artifact is the universal immutable unit manipulated by Miova.
It contains:
kind— domain identifierpayload— domain-specific contentid— generated artifact identitymetadata— additional informationlineage— transformation ancestry
Example:
from miova import Artifact
artifact = Artifact(
kind="yaml",
payload={
"site_name": "Miova",
"theme": {
"name": "material",
},
},
)
Miova treats the payload as opaque. Domain-specific interpretation belongs to adapters.
Adapter
An adapter bridges Miova artifacts and domain objects.
The execution flow is:
Artifact
|
v
Adapter.extract()
|
v
Domain Object
|
v
Mutation
|
v
Domain Object
|
v
Adapter.build()
|
v
Artifact
Adapters allow Miova to remain domain-agnostic.
Mutation
A mutation is a small executable transformation.
It receives a domain object and a runtime context, then returns a new domain object.
A mutation does not manage:
- artifact identity
- lineage
- validation
- reporting
- adapter resolution
Those responsibilities belong to the framework runtime.
Mutation Contract
A mutation contract describes the semantic purpose of a mutation.
It defines:
- intent
- expected outcome
- applicability
- rationale
Example:
from miova import MutationContract
contract = MutationContract(
intent="Add a summary section",
expected_outcome="The document contains a Summary section",
applicability=lambda artifact, context: artifact.kind == "document",
rationale="Used to explore valid document variants",
)
Contracts describe why a mutation exists and when it may run.
Invariants
Invariants define properties that must remain valid.
Miova supports two kinds of invariants.
State invariants
State invariants validate a single artifact.
Examples:
- document has a title
- YAML payload is a mapping
- graph has at least one node
- DSL property is syntactically valid
Transition invariants
Transition invariants validate a transformation.
Examples:
- artifact kind is preserved
- required metadata is preserved
- a mutation only changes the expected field
- a transformation preserves semantic consistency
Pipeline
A MutationPipeline executes a sequence of mutation definitions.
Artifact
|
v
Mutation A
|
v
Artifact A'
|
v
Mutation B
|
v
Artifact B'
|
v
Final Artifact
The pipeline stops as soon as a mutation returns a non-success status.
Campaign
A campaign runs multiple generated pipelines over the same initial artifact.
Initial Artifact
|
+-- Generated Pipeline 1
|
+-- Generated Pipeline 2
|
+-- Generated Pipeline 3
|
+-- Campaign Result
Campaigns are useful for:
- automated exploration
- mutation-based testing
- property-based testing
- fuzzing-like workflows
- robustness analysis
Reporting
Miova includes generic payload-level reporting.
Instead of only displaying artifact objects before and after a mutation, Miova can report what changed inside the payload.
Example output:
Mutation: yaml_add_version
Status: SUCCESS
Payload changes:
+ version:
'0.1.0'
Pipeline and campaign reports can also display step-by-step mutation changes.
Execution flow
A mutation execution follows this lifecycle:
sequenceDiagram
participant User
participant Engine
participant Contract
participant InvariantEngine
participant Adapter
participant Mutation
participant Reporter
User->>Engine: apply(artifact, mutation definition)
Engine->>Contract: check applicability
Contract-->>Engine: applicable
Engine->>InvariantEngine: validate initial state
InvariantEngine-->>Engine: valid
Engine->>Adapter: extract domain object
Adapter-->>Engine: domain object
Engine->>Mutation: execute mutation
Mutation-->>Engine: mutated domain object
Engine->>Adapter: build new artifact
Adapter-->>Engine: new artifact
Engine->>InvariantEngine: validate generated artifact and transition
InvariantEngine-->>Engine: valid
Engine-->>User: MutationResult
User->>Reporter: render result
Reporter-->>User: payload-level report
Possible mutation statuses:
SUCCESSSKIPPEDREJECTEDFAILED
Quick example
A complete Miova runtime usually contains:
- an artifact
- an adapter
- one or more mutations
- contracts
- invariants
- a context
- an engine
- optional reporting
Conceptual usage:
from miova import Artifact, MiovaEngine
from miova.reporting import print_mutation_result
artifact = Artifact(
kind="example",
payload={
"name": "Miova",
},
)
context = create_context_with_adapters_mutations_and_invariants()
definition = context.mutation_registry.get(
"example_mutation"
)
engine = MiovaEngine()
result = engine.apply(
artifact=artifact,
definition=definition,
context=context,
)
print_mutation_result(
result,
context,
)
For complete executable examples, see:
python -m examples.document.run_engine
python -m examples.document.run_pipeline
python -m examples.document.run_campaign
python -m examples.yaml.run_engine
python -m examples.yaml.run_pipeline
python -m examples.yaml.run_campaign
Declarative mutation example
Miova supports declarative registration through decorators.
from miova import (
MutationContract,
MutationNature,
MutationStrategy,
PreservationLevel,
PreservationProfile,
mutation,
)
contract = MutationContract(
intent="Add a summary section",
expected_outcome="The document contains a Summary section",
applicability=lambda artifact, context: artifact.kind == "document",
rationale="Used to explore valid document variants",
)
preservation = PreservationProfile(
structure=PreservationLevel.PARTIAL,
behavior=PreservationLevel.FULL,
semantics=PreservationLevel.FULL,
information=PreservationLevel.FULL,
)
@mutation(
name="add_summary_section",
nature=MutationNature.INSERTION,
strategy=MutationStrategy.PRESERVING,
contract=contract,
preservation=preservation,
severity=0.2,
)
def add_summary_section(document, context):
return document.with_section("Summary")
The mutation is registered when the module is imported.
This enables a simple user workflow:
declare mutations
declare invariants
register adapter
create context
run engine / pipeline / campaign
render report
Installation
For local development:
python -m pip install -e ".[dev]"
Run the test suite:
python -m pytest
Build the documentation:
mkdocs build --strict
Check package import:
python -c "from miova import Artifact, MiovaEngine"
Documentation
The documentation is available in the /docs directory and can be served locally with:
mkdocs serve
The documentation covers:
- architecture
- core concepts
- adapters
- registries
- reporting
- examples
- ADRs
- roadmap
Examples
Miova currently includes example domains:
Document example
Demonstrates:
- dataclass payloads
- document adapter
- declarative mutations
- state invariants
- transition invariants
- engine execution
- pipeline execution
- campaign execution
- payload-level reporting
Run:
python -m examples.document.run_engine
python -m examples.document.run_pipeline
python -m examples.document.run_campaign
YAML example
Demonstrates:
- YAML-like structured payloads
- nested dictionary/list mutation
- reportable adapter hook
- payload diff reporting
- pipeline and campaign reporting
Run:
python -m examples.yaml.run_engine
python -m examples.yaml.run_pipeline
python -m examples.yaml.run_campaign
Design principles
Miova is built around the following principles.
Domain independence
The framework does not assume a specific artifact type.
Domain logic belongs to adapters.
Explicit semantics
Mutations are described through contracts.
The framework can reason about intent, applicability and expected outcomes.
Validation-first execution
Transformations are checked through state and transition invariants.
Invalid transformations are rejected.
Immutability and lineage
Mutations create new artifacts instead of modifying existing ones.
Each artifact keeps track of its ancestry.
Observability
Mutation, pipeline and campaign results can be rendered as human-readable reports showing payload-level changes.
Composability
Small mutations can be composed into pipelines.
Pipelines can be generated and executed as campaigns.
Testing
Miova is covered by three levels of tests.
P0
Core framework behavior:
- artifact model
- engine statuses
- pipeline execution
- registries
- decorators
- invariants
- reporting
- examples
- regression tests
P1
Framework integration quality:
- public imports
- multi-domain runtime
- mutation filtering
- mutation selection
- pipeline generation
- documentation build
- no domain leakage
P2
Robustness:
- property-based tests
- serializer and differ properties
- engine result properties
- reporting smoke tests
- campaign reporting limits
Run all tests:
python -m pytest
Roadmap
Possible future directions:
- richer mutation generation strategies
- weighted mutation selection
- optimization-driven exploration
- distributed mutation campaigns
- advanced campaign analytics
- additional domain adapters
- FORML adapter
- Python AST adapter
- graph adapter
- JSON adapter
- ML model configuration adapter
License
Miova is licensed under the Apache License 2.0.
See the LICENSE file for details.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file miova-0.1.0.tar.gz.
File metadata
- Download URL: miova-0.1.0.tar.gz
- Upload date:
- Size: 31.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fa3acfa51c07cddd5f92ea4ceeb2a0e3077858068310db0565033ce9921f9e95
|
|
| MD5 |
893f1ea9411beec74717144bb7d5c56b
|
|
| BLAKE2b-256 |
44e1ed23ab5b9d4438169826e79f81c55b6880d961e4c58fd95230218a6641db
|
File details
Details for the file miova-0.1.0-py3-none-any.whl.
File metadata
- Download URL: miova-0.1.0-py3-none-any.whl
- Upload date:
- Size: 39.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4b98300989602b637ab66545a5aeed607c9ebecd7a524f35deeb2357e2e2ad42
|
|
| MD5 |
79972ff3661af8c38c1cee79fa529fca
|
|
| BLAKE2b-256 |
793d9134fa69414c2b5274de07aea24f052f50809bb1bd20c305f81d6791fc0a
|