Skip to content

Polylith Architecture

G6Solver uses the Polylith architecture -- a monorepo pattern where code is organized into composable bricks that are assembled into deployable projects.

Why Polylith?

Traditional monorepos couple delivery mechanisms to business logic. Polylith separates them:

  • Components contain pure logic with no knowledge of how they are delivered
  • Bases are thin protocol adapters (REST, MCP, CLI, etc.)
  • Projects assemble components + bases into deployable artifacts

This means the same formal_methods component works identically whether accessed via MCP, REST, gRPC, or CLI.

Workspace configuration

The workspace is configured in workspace.toml:

[tool.polylith]
namespace = "mvp"
theme = "loose"
  • namespace = mvp -- all bricks live under the mvp Python namespace
  • theme = loose -- components are at components/mvp/<name>/ (not components/<name>/mvp/<name>/)

Directory structure

mvp_v1/
├── workspace.toml              # Polylith config
├── pyproject.toml              # Root workspace (dev deps: pytest, mypy, ruff)
├── development/
│   └── pyproject.toml          # All bricks, package-mode=false
├── components/
│   └── mvp/
│       ├── core/               # Result[T], AIBlock, SearchTree
│       ├── config/             # Settings via pydantic-settings
│       ├── llm_router/         # Model-agnostic LLM interface
│       ├── goal_engine/        # Goal decomposition (175 MCP ops)
│       ├── formal_methods/     # SAT/SMT/DPLL/Z3 (405 tools)
│       ├── csf/                # Safety verification
│       ├── cegis/              # Counterexample-guided synthesis
│       └── ...                 # 270 registry components total
├── bases/
│   └── mvp/
│       ├── cli/                # Textual TUI
│       ├── rest/               # FastAPI
│       ├── mcp/                # FastMCP
│       ├── grpc/               # betterproto
│       ├── soap/               # spyne
│       └── erlang/             # Custom protocol
├── projects/
│   ├── g6_tui/                 # CLI deployable
│   ├── g6_mcp/                 # MCP server deployable
│   └── g6_rest/                # REST API deployable
└── tests/
    └── mvp/                    # Test suites

Brick types

Components (270)

Pure Python modules with no delivery-mechanism coupling. Each component is a focused cognitive capability built on the AIBlock[Input, Output, State] pattern.

Components are organized by intelligence class:

Category Components Description
Core Infrastructure core, config, llm_router, database Foundation types and configuration
Self-Learning adapt_memory, adapt_pandas, adapt_sklearn, adapt_optimisation, adapt_pygad Memory, data, ML, optimization
Self-Modification meta_programming, cegis, adapt_healing Code rewriting and synthesis
Failure Engineering csf, grounding Safety verification and knowledge grounding
Alignment align_specs, align_evals, align_csf, align_prompt_library Specification and evaluation
Formal Methods formal_methods SAT, SMT, DPLL, Z3 (405 tools)
Symbolic ML ctx_rag, ctx_colbert, ctx_elastic, ctx_search, ctx_recursive, ctx_cognee, ctx_langextract, ctx_scrapling, ctx_markitdown Retrieval and extraction
Agents agent_claude, goal_engine LLM agent interfaces
Job Agents job_framework + 32 job_<name> Task-specific agent components

Bases (11)

Delivery mechanisms -- thin adapters that expose components via different protocols:

Base Protocol Framework Entry Point
cli Terminal UI Textual + Click python -m mvp.cli
rest HTTP/REST FastAPI + Uvicorn python -m mvp.rest
mcp MCP (SSE/stdio) FastMCP python -m mvp.mcp
grpc gRPC betterproto python -m mvp.grpc
soap SOAP/XML spyne python -m mvp.soap
erlang Custom Custom protocol python -m mvp.erlang
web HTTP Django python -m mvp.web

Each base provides three helper functions:

  • _list_components() -- enumerate registered components
  • _invoke_component(name, op, params) -- call a component operation
  • _run_pipeline(steps) -- execute a pipeline

Projects (3)

Deployable artifacts that assemble specific bases + components:

  • g6_tui -- CLI application
  • g6_mcp -- MCP server deployment
  • g6_rest -- REST API deployment

Each project has its own pyproject.toml with pinned dependencies including returns and trio.

Adding a new brick

New component

  1. Create the directory structure:

    components/mvp/my_component/
    ├── __init__.py      # Public exports
    ├── schema.py        # Pydantic Input/Output models
    └── block.py         # AIBlock subclass
    
  2. Implement the AIBlock subclass:

    from mvp.core import AIBlock, Result
    
    class MyBlock(AIBlock["MyInput", "MyOutput", None]):
        name: str = "my_component"
    
        def infer(self, input: "MyInput") -> Result["MyOutput"]:
            # Implementation here
            return Result.ok(MyOutput(...))
    
  3. Export from __init__.py:

    from mvp.my_component.schema import MyInput, MyOutput
    from mvp.my_component.block import MyBlock
    
    __all__ = ["MyInput", "MyOutput", "MyBlock"]
    
  4. The ComponentRegistry auto-discovers the component at import time.

New base

  1. Create the directory at bases/mvp/<name>/
  2. Implement protocol adapter using _list_components, _invoke_component, _run_pipeline helpers
  3. Add a Dockerfile at bases/mvp/<name>/Dockerfile
  4. Add per-base skills at bases/mvp/<name>/skill/

Inspecting the workspace

# View all bricks and their dependencies
poetry poly info

# List component directories
ls components/mvp/

# List base directories
ls bases/mvp/

See Component Model for details on how AIBlock and Result[T] work.