HunterX v7 Platform Composition Root — Architecture & Reference

Status: Ratified (Sprint 006.6) Version: 1.0.0 Owner: HunterX Architecture Council


1. Purpose / Scope

This document defines the Platform Composition Root — the single place where every concrete implementation in HunterX v7 is selected and wired together at startup.

It has two mandates:

  1. Compose. Build a fully wired Platform runtime aggregate: settings, infrastructure adapters, persistence repositories, the four v7 facades, the Core Engine, application services, and a dependency container that resolves every port and service.
  2. Expose. Give the API, CLI, and tests one entry point (hunterx.platform.build_platform) that returns the same wiring everywhere, so handlers, commands, and tests never construct collaborators directly.

Hard constraints:

Scope: src/hunterx/platform/, src/hunterx/infrastructure/memory/, the CoreEngine v7-facade fields, api/app.py, api/deps.py, cli/commands.py and tests/unit/test_platform.py.

Out of scope: real cache/queue/AI adapters (Redis, providers), REST routes for each service (later sprints), mission scheduling/dispatch, and database schema design.


2. Design Goals

  1. One wiring path. Every entry point (API, CLI, tests, scripts) builds the platform the same way and shares the same container.
  2. Explicit dependency graph. The assembler registers every port and service by concrete type, so container.resolve(X) is unambiguous.
  3. Runnable out of the box. Defaults are in-memory; the platform starts with zero configuration and zero external services.
  4. Swappable persistence. SQL entity repositories activate when a non-default database.url is configured and SQLAlchemy is importable, without touching any consumer code.
  5. Observable composition. The CLI platform command reports the exact backend, repository, facade and service classes actually wired.

3. Package Overview

src/hunterx/
├── platform/
│   ├── __init__.py        # re-exports Platform, build_platform
│   ├── platform.py        # Platform runtime aggregate (dataclass)
│   └── assembler.py       # build_platform + private wiring helpers
└── infrastructure/
    └── memory/
        ├── __init__.py    # re-exports in-memory repositories
        ├── repositories.py # core entity repositories + builder
        ├── planning.py    # mission planning repositories + builder
        └── factory.py     # tool factory repositories + builder
flowchart TD
    ENTRY[API / CLI / tests / scripts] --> BUILD[build_platform]
    BUILD --> ASM[assembler]
    ASM --> SET[load Settings]
    ASM --> ADAPT[build adapters]
    ASM --> REPO[build repositories]
    ASM --> TIP[ToolIntelligenceAPI]
    ASM --> SDK[ExecutionEngine]
    ASM --> FAC[ToolIntegrationFactory]
    ASM --> MP[MissionPlanningAPI]
    ASM --> ENG[CoreEngine + engines]
    ASM --> SVC[application services]
    ASM --> REG[register ports & services in Container]
    BUILD --> PLAT[Platform aggregate]
    PLAT --> CTX[container]

4. The Platform Aggregate

Platform (src/hunterx/platform/platform.py) is a slotted dataclass that owns the runtime. Attributes:

Attribute Type Meaning
settings Settings resolved typed configuration
container Container[Any] dependency container (every port + service)
core CoreEngine the aggregated engine (all engines + v7 facades)
tip ToolIntelligenceAPI Tool Intelligence Platform facade
execution_engine ExecutionEngine Tool Integration SDK engine
tool_factory ToolIntegrationFactory Tool Integration Factory facade
mission_planning MissionPlanningAPI mission planning engine facade
mission_service MissionService mission use-case service
finding_service FindingService finding use-case service
report_service ReportService report use-case service
tool_factory_service ToolFactoryService factory use-case service
mission_planning_service MissionPlanningService planning use-case service
event_bus EventBusPort event bus adapter
cache CachePort cache adapter
queue QueuePort work-queue adapter
secrets SecretsPort secrets adapter
ai AIPort AI provider adapter
telemetry TelemetryPort telemetry adapter
knowledge_graph KnowledgeGraphPort knowledge graph adapter
repositories dict[str, object] concrete repositories keyed by role

Helpers: resolve(key) and has(key) delegate to the container.


5. Assembler Wiring

build_platform(settings=None) (in assembler.py) is the composition root. Order of construction:

5.1 Settings & infrastructure

5.2 Persistence (_build_repositories)

All 13 roles default to in-memory repositories (_MEMORY_REPOSITORIES maps role → concrete class):

Role In-memory class
missions InMemoryMissionRepository
findings InMemoryFindingRepository
targets InMemoryTargetRepository
scans InMemoryScanRepository
assets InMemoryAssetRepository
reports InMemoryReportRepository
mission_profiles InMemoryMissionProfileRepository
mission_templates InMemoryMissionTemplateRepository
mission_plans InMemoryMissionPlanRepository
checkpoints InMemoryCheckpointRepository
mission_timeline InMemoryMissionTimelineRepository
pack_templates InMemoryPackTemplateRepository
tool_packs InMemoryToolPackRepository

SQL switching: when settings.database.url is set and differs from the default sqlite:///hunterx.db and SQLAlchemy is importable, the six entity roles swap to Sql*Repository(session_factory); create_all() runs and "session_factory" is added to the repositories dict. Planning and factory repositories always stay in-memory.

5.3 v7 facades

5.4 Core Engine

CoreEngine aggregates the engines and carries the v7 facades. New optional fields: tip, execution_engine, tool_factory, mission_planning.

flowchart LR
    core[CoreEngine] --> me[MissionEngine]
    core --> we[WorkflowEngine]
    core --> pl[DeterministicPlanner]
    core --> co[TargetCorrelator]
    core --> rs[DefaultRiskScorer]
    core --> re[ReasoningEngine]
    core --> rp[ReportEngine]
    core --> tip[ToolIntelligenceAPI]
    core --> sdk[ExecutionEngine]
    core --> fac[ToolIntegrationFactory]
    core --> mp[MissionPlanningAPI]

5.5 Container registration (_register_ports)

Registered instances:


6. Repository Ports & Adapters

The in-memory adapters in hunterx.infrastructure.memory are the canonical reference implementations of the repository ports. Each class implements one port and is used both by the platform (default persistence) and the test suite’s framework doubles.

Behavior notes:


7. API & CLI Entry Points

7.1 REST API (api/app.py, api/deps.py)

create_app(settings=None, *, register_health=True, platform=None):

7.2 CLI (cli/commands.py)

register_default_commands(app, platform=None) registers version, help, config, and platform. The platform command prints a JSON report: environment, cache/queue backends, repository class per role, facade classes and service classes — the observable composition of the running platform.


8. Architecture Rules

  1. hunterx.platform is the ONLY package allowed to import both domain and infrastructure and bind them.
  2. Components MUST receive collaborators through constructors or the container; no service-locator lookups inside domain/application/engine code.
  3. The platform MUST assemble with zero configuration using in-memory adapters; any external service is an opt-in.
  4. Entity repositories MAY be SQL-backed when configured; planning/factory repositories are in-memory-only until SQL adapters exist.
  5. Every public contract SHALL have a docstring; the package SHALL lint clean under the configured ruff gates and pass the test suite.

9. Developer Guide

Building a platform

from hunterx.platform import build_platform

platform = build_platform()
core = platform.core
tip = platform.tip                     # ToolIntelligenceAPI
engine = platform.execution_engine     # ExecutionEngine

Configuring SQL persistence

from hunterx.config.settings import DatabaseSettings, Settings

settings = Settings(database=DatabaseSettings(url="postgresql://hx:hx@db/hunterx"))
platform = build_platform(settings)
assert "session_factory" in platform.repositories

Inspecting composition from the CLI

hunterx platform
# {"environment": "production", "cache_backend": "memory", ...}

Wiring the API

from hunterx.api.app import create_app
from hunterx.platform import build_platform

platform = build_platform()
app = create_app(platform=platform)   # handlers resolve the platform's services

Testing

tests/unit/test_platform.py covers assembly (facades, services, adapters, repository roles), container resolution (every port and service), backend selection from settings, SQL switching, and API/CLI wiring.


10. Verification

Gated by:

Acceptance Checklist


11. Out of Scope

Real cache/queue/AI adapters, per-service REST routes, SQL adapters for mission-planning and factory repositories, and mission scheduling/dispatch.