Architecture & modules¶
This page is the map for reading the code: how a scan flows from a target to a kept test, and where each piece lives. If you want to extend Mylonite, pair this with Plugin authoring.
Two validation layers¶
Everything in Mylonite answers one of two questions:
- Layer 1 — "did the attack land?" (is one attempt a finding) → a deterministic predicate, then an LLM judge if inconclusive, then an effect probe. See Weakness classes.
- Layer 2 — "is the finding worth a committed test that gates CI?" (is it kept) → the differential oracle. See The validation engine.
The flow¶
target ──> scan (Layer 1) ──> generate ──> validate (Layer 2) ──> gate ──> PR / CI
findings pytest file kept? workflows
Module map¶
Scanning & attacks — mylonite.scan¶
engine.py—ScanEngine: the single-shot orchestrator (customise → invoke → judge, with the scan-time flakiness filter and the LLM-call budget).seeds.py/predicates.py— the bundled attack seeds (W1–W4) and the deterministic success predicates.judge.py— the Layer-1 success ladder (predicate → LLM judge → effect probe).seed_synth.py— descriptor-driven seed synthesis: builds attack seeds for the channels a target's introspected tool surface actually supports (a direct-content tool, a poisoned tool description, …), so a target that doesn't match the bundled kitchen-sink's plant/recall shape still gets a runnable probe instead of a skip.control_shim.py— theBoundaryControlsubclasses (W1–W4) andControlServerShimthat synthesize a boundary-guarded build of any target (a server-layer control needscontrol_env); the control-efficacy check.tool_roles.py— heuristics that classify a tool surface (store / retrieve / sink).artefacts.py— the terminal trust panel.
The validation engine — mylonite.plugins._reference.reference_validator¶
DifferentialValidator implements the oracle legs: build · differential · flakiness ·
metamorphic (gating, incl. the evasion encodings) · mutation score (report-only),
plus the custom-target legs stability · effect · consensus. The honesty invariant
(plant + effect probe bypass the control) lives here and in control_shim.py.
Targets — mylonite.plugins._mcp & _reference¶
_mcp/stdio_adapter.py—MCPStdioAdapter(drives any stdio MCP server) + the bundled family adapters (filesystem/fetch/github) + theAttackSession(stateful, multi-turn) used to plant and drive across turns._mcp/remote_adapter.py—MCPRemoteAdapter: connects to a remote MCP server over SSE / streamable-HTTP (transport: sse|http+urlin thetarget.yaml), a first-class transport alongside stdio._mcp/target_file.py— thetarget.yamlmodel + auto-wiring._mcp/target_registry.py— the bundled familyTargetSpecs._reference/reference_target_adapter.py— the in-process reference app builds (reference:vulnerable/reference:guarded), the ground-truth differential.
Outputs — mylonite.report & mylonite.gate¶
report/sarif.py,report/bundle.py,report/severity.py— the SARIF / JSON renderers + shared severity rule.gate/orchestrator.py— the scan→generate→validate→PR sequence + exit codes.gate/mitigation.py+gate/recommend.py— the PR body and the target-specific, evidence-anchored recommendation (a fenced code sketch, never a diff).gate/localize.py+gate/annotate.py— pin a finding to its locus and post inline PR check-run annotations.gate/pr.py/gate/workflows.py— the git/ghPR flow and CI workflow templates.
Compliance — mylonite.taxonomy¶
The bundled OWASP-LLM / OWASP-ASI / MITRE ATLAS / NIST data and the mapper that stamps every finding. See Standards mapping.
The five extension contracts — mylonite.contracts¶
Public API from day one (versioned Protocol/ABCs + JSON schemas + entry-point loading):
| Contract | Role | Reference impl |
|---|---|---|
AttackModule |
generate payloads for a target | PromptInjectionAttackModule, … |
TargetAdapter |
speak to a target (sync/async; optional SupportsAttackSession) |
MCPStdioAdapter, InProcessReferenceAdapter |
TestGenerator |
emit a regression test | ReferencePytestGenerator |
Validator |
the differential oracle | DifferentialValidator |
ComplianceMapper |
tag with OWASP/ATLAS/NIST | ReferenceComplianceMapper |
Plugins are discovered via setuptools entry-point groups
(mylonite.attack_modules, mylonite.validators, …). Treat any change to a contract as
an API change — see Plugin authoring.
Constraints worth knowing¶
- All LLM access flows through LiteLLM — no provider SDKs imported directly; there's no default provider (you must configure one). This is what makes the model roles possible.
- The reference app is ground truth. The bundled
mcp_kitchen_sinkvulnerable/guarded pair is intentionally (un)guarded; the differential is proven against it. - Scope discipline. Only the AI attack surface — no general SAST/DAST, no non-AI test generation.
- Output and paths are funneled, not ad hoc. Everything printed, persisted, pushed, or
published goes through
mylonite._cli_io.echo/_redaction.redact*; every path sourced fromtarget.yamlresolves throughmylonite._paths.resolve_containedbefore it reachesopen()or an argv — no directtyper.echocalls or unchecked paths remain incli.py.