how the code stays changeable
Strong boundaries.
Few surprises.
The design favors small domain contracts, explicit failure behavior, and composition over inheritance. Add an implementation without making the core know about your infrastructure.
Module boundaries
schema.pyowns validated wire and domain data.graph.pyowns pure graph transformations and invariants.adapter.pyowns runtime orchestration around a host solver.llm.pyowns provider I/O, timeouts, bounded output, and retries.repo.pyowns durable persistence behind protocols.jobs.pyowns durable evolution records and workers.service.pyowns HTTP DTOs, auth, readiness, and transport errors.
Structural polymorphism
Runtime dependencies are substituted through typing.Protocol contracts: Solver, LLMClient, Repository, VectorIndex, and ActionExecutor. This is the OOP seam: behavior is replaceable without forcing every host into a class hierarchy.
class Solver(Protocol):
async def step(self, state: AgentState) -> str: ...
class TestSolver:
async def step(self, state: AgentState) -> str:
return "answer"Style and naming
Public APIs use Google-style snake_case, PascalCase, and UPPER_SNAKE_CASE. Implementation-only state uses one leading underscore, such as self._pool. Double-leading underscores are reserved for language protocols and name-mangling cases.
Ruffmypyabsolute imports__all__no lazy imports
Testing contract
The quality gate includes linting, formatting, typing, unit/API tests, Postgres integration, browser accessibility, container startup, load smoke tests, backup/restore, SBOM, and vulnerability scanning. The local integration recipe is on the testing guide.
uv run ruff check .
uv run ruff format --check methodos tests scripts eval/hotpotqa/*.py examples
uv run mypy methodos tests scripts eval/hotpotqa/*.py examples
uv run pytest -q --cov=methodos --cov-fail-under=95