Skip to content

Plugin authoring

Mylonite has five versioned extension points, each defined as a Python Protocol + a runtime-checkable ABC under src/mylonite/contracts/. Plugins register via standard PyPI entry points and are discovered by mylonite.plugins.registry.discover.

Versioning rules

Every contract module exports a CONTRACT_VERSION semver string. Every plugin class declares its own contract_version. The loader:

  • refuses to load a plugin whose declared contract_version differs in major version from the host,
  • warns on minor mismatches,
  • ignores patch differences.

This is enforced at discovery time so a pip install of a mismatched plugin never fails silently mid-run.

Entry-point groups

Contract Entry-point group Reference impl
Attack module mylonite.attack_modules mylonite.plugins._reference.reference_attack_module
Target adapter mylonite.target_adapters mylonite.plugins._reference.reference_target_adapter
Test generator mylonite.test_generators mylonite.plugins._reference.reference_pytest_generator
Validator mylonite.validators mylonite.plugins._reference.reference_validator
Compliance mapper mylonite.compliance_mappers mylonite.plugins._reference.reference_compliance_mapper

Registering a plugin

In your own package's pyproject.toml:

[project.entry-points."mylonite.attack_modules"]
my_attack = "my_package.module:MyAttackModule"

The class must:

  • declare contract_version: ClassVar[str] matching AttackModule.CONTRACT_VERSION,
  • be instantiable with no arguments (config flows via the contract's methods),
  • implement the methods in the Protocol.

Worked examples

Each reference plugin in src/mylonite/plugins/_reference/ is intentionally minimal. Use them as starting points.

JSON schemas

The wire-format JSON schemas for the Pydantic models passed between plugins live under src/mylonite/schemas/ and are regenerated via:

python scripts/regenerate_schemas.py

CI checks they are up to date after any contract change.