MADDENING uses the prefix MADD for all identifiers:
| Category | Format | Example |
|---|---|---|
| Node algorithm IDs | MADD-NODE-XXX |
MADD-NODE-001 |
| Anomaly IDs | MADD-ANO-XXX |
MADD-ANO-001 |
| Verification benchmark IDs | MADD-VER-XXX |
MADD-VER-001 |
MADDENING uses a three-phase anomaly lifecycle:
When you discover a bug or anomaly:
- Create a GitHub Issue using the anomaly template (
.github/ISSUE_TEMPLATE/anomaly.md) - Fill in all mandatory fields: severity, safety relevance, rationale, affected components, affected versions, workaround
- Apply the appropriate labels:
anomaly:critical,anomaly:major, oranomaly:minor - If the anomaly could affect numerical correctness in a safety-relevant context, also apply the
safety-relevantlabel
Once the anomaly is confirmed and understood:
- Add an entry to
docs/validation/known_anomalies.yaml - The entry must follow the schema:
anomaly_id,title,description,severity,safety_relevance,safety_relevance_rationale - Run
python -m maddening.compliance check-anomalies docs/validation/known_anomalies.yamlto validate - Cross-reference the GitHub Issue number in the YAML entry
When the anomaly is resolved:
- Update the YAML entry with resolution status and version
- Add or update verification tests that demonstrate the fix
- Never delete anomaly entries — mark them as resolved
- Tier 1 (
safety-relevant): YAML entry required before release — no exceptions - Tier 2 (
anomaly:criticaloranomaly:major): YAML entry required before release — no grace period - Tier 3 (
anomaly:minor): Two-cycle grace period; CI warns after one release cycle, blocks after two
- NumPy-style docstrings
- All node
update()functions must be JAX-traceable (no Python-level side effects) - All new nodes must have a
metaClassVar withNodeMeta
pip install -e ".[dev]" # all features + pytest
# Or for GPU development:
pip install -e ".[dev,cuda12]"See docs/user_guide/installation.md for all available extras.
Run the test suite:
PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 python -m pytest tests/ -v --tb=shortWhen writing code that uses an optional dependency, wrap the import with a try/except that tells the user which extra to install:
# Module-level guard (for modules dedicated to one dep)
try:
import pyvista as pv
except ImportError as _exc:
raise ImportError(
"HistoryViewer3D requires 'pyvista'. "
"Install with: pip install maddening[viz3d]"
) from _exc
# Lazy import guard (in __getattr__)
try:
mod = importlib.import_module(module_path)
return getattr(mod, name)
except ImportError as exc:
raise ImportError(
f"'{name}' requires additional dependencies. "
f"Install with: pip install maddening[extra_name]"
) from excThe error message must always contain the exact pip install maddening[...] command.
Every SimulationNode subclass must have a meta ClassVar containing at minimum:
algorithm_id(usingMADD-NODE-XXXformat)stability(StabilityLevel enum)descriptionassumptionslimitationshazard_hints