Skip to content

System Architecture

Overview

Ananke Plexus follows a core + ports + adapters hexagonal architecture. The stable center contains Ananke's governance semantics. External tooling remains fully replaceable.

flowchart TB
    subgraph Entry["πŸ‘€ Entrypoints"]
        CLI["⌨️ ananke CLI"]
        APMCLI["πŸ“¦ apm CLI"]
        HOOKS["πŸͺ Git Hooks"]
        MCP["πŸ”Œ MCP Clients"]
        CI["βš™οΈ CI/CD"]
    end

    subgraph Core["βš–οΈ Ananke Core"]
        CONFIG["βš™οΈ Config"]
        POLICY["πŸ›‘οΈ Policy Engine"]
        EXEC["πŸ€– Execution Director"]
        EVENTS["πŸ“‘ Event Bus"]
        TELEMETRY["πŸ“Š Telemetry"]
        PERM["πŸ” Permissions"]
        STATE["πŸ” Run State Machine"]
    end

    subgraph Domain["🧠 Domain Subsystems"]
        SPEC["πŸ“œ Spec / BMAD"]
        CALM["πŸ—οΈ CALM Architecture"]
        GRAPH["πŸ•ΈοΈ Graph Intelligence"]
        APM["πŸ“¦ APM"]
        REGISTRY["πŸ—‚οΈ Skill & Agent Registry"]
        GATES["πŸ§ͺ Verification Gates"]
        EVIDENCE["🧾 Evidence"]
    end

    subgraph Adapters["πŸ”Œ Adapters"]
        JIRA["Jira"] 
        SCM["GitHub / Bitbucket"]
        GRAPHIFY["Graphifyy"]
        CRG["Code Review Graph"]
        COPILOT["Copilot"] 
        Q["Amazon Q"]
        KIRO["Kiro"]
        HERMES["Hermes"]
    end

    Entry --> Core
    Core --> Domain
    Domain --> Adapters
    Adapters -. Results .-> Domain

Package layout

ananke-plexus/
└── src/ananke/plexus/
    β”œβ”€β”€ cli/            β€” Typer CLI entrypoints (ananke + apm)
    β”œβ”€β”€ core/           β€” IDs, result types, path helpers, workflow audit
    β”œβ”€β”€ config/         β€” Config models, loader, migration, secrets resolver
    β”œβ”€β”€ contracts/      β€” BMAD compiler: behavior, model, architecture
    β”œβ”€β”€ specs/          β€” Spec models, service, providers, lock, drift
    β”œβ”€β”€ architecture/   β€” CALM loader, validation, delta, Mermaid rendering
    β”œβ”€β”€ graph/          β€” Canonical graph models, providers (native/Graphifyy/CRG)
    β”œβ”€β”€ policy/         β€” Policy engine, rule schema, builtin packs
    β”œβ”€β”€ gates/          β€” Gate runner, adapters (ruff, mypy, pytest, semgrep...)
    β”œβ”€β”€ execution/      β€” Plan DAG, scheduler, checkpoint, approvals, compensation
    β”œβ”€β”€ backends/       β€” AgentBackend protocol, Copilot/Q/Kiro/Hermes/fake adapters
    β”œβ”€β”€ lifecycle/      β€” Git service, worktrees, Jira, Bitbucket, PR evidence
    β”œβ”€β”€ hooks/          β€” Git hook manager, stages, runner
    β”œβ”€β”€ mcp/            β€” MCP server, tools, resources, prompts, auth
    β”œβ”€β”€ apm/            β€” Skill manifests, registry, installer, sandbox, lockfile
    β”œβ”€β”€ evidence/       β€” Evidence bundle, SARIF 2.1.0, hash, retention (+ registry capability snapshot)
    β”œβ”€β”€ registry/       β€” Skill & Agent Registry: SQLite + content-addressed store, importers,
    β”‚                     resolver, ananke.lock, activation, docs generator, HTTP server
    β”œβ”€β”€ evals/          β€” Enterprise evaluation harness: traces, evaluators, judges, regression
    β”œβ”€β”€ testing/        β€” Unified test & quality harness: adapters, profiles, quality gate
    β”œβ”€β”€ events/         β€” In-process event bus with JSONL audit log
    β”œβ”€β”€ telemetry/      β€” OpenTelemetry adapter, noop
    └── plugins/        β€” Entry-point discovery, plugin metadata

Design principles

Local-first

Code, specs, graph state, verification, and evidence can remain entirely local. No hosted service is required.

Ports and adapters

Every external integration is isolated behind a protocol/interface:

GraphProvider  β†’  NativeGraphProvider | GraphifyyAdapter | CodeReviewGraphAdapter
AgentBackend   β†’  CopilotBackend | AmazonQBackend | KiroBackend | HermesBackend | FakeBackend
SCMPort        β†’  BitbucketAdapter | GitHubAdapter
IssuePort      β†’  JiraAdapter
ScannerPort    β†’  RuffAdapter | SemgrepAdapter | GitleaksAdapter | TrivyAdapter

Immutable, content-addressed capabilities

Skills and agents live in the registry: every version is an immutable, hash-verified payload; mutable state (trust, channel, lifecycle) is separate and audited. Resolution is deterministic, policy-aware and explainable, and produces a reproducible ananke.lock.

Fail closed for hard gates

When a configured hard gate cannot execute, the default result is BLOCKED, not "pass."

Soft gates return: PASS | WARN | SKIPPED | UNAVAILABLE
Hard gates return: PASS | BLOCKED | ERROR

Evidence before mutation

Every mutating step records:

  1. Requested intent
  2. Policy decision
  3. Preconditions
  4. Execution result
  5. Verification result
  6. Artifact hashes
  7. Audit record

Capability discovery

Every backend declares a BackendCapabilities model. The orchestrator asks the registry for capabilities and constructs a compatible execution plan.


Configuration precedence

Highest wins:

  1. CLI flags (--project, --offline, --json)
  2. Process environment variables
  3. .ananke/config.local.toml
  4. .ananke/config.toml
  5. User config
  6. Built-in defaults

Event system

Every subsystem emits typed domain events to an in-process event bus. Events are appended to .ananke/evidence/*.jsonl for audit trails.

Registry events (artifact.registered, artifact.promoted, artifact.yanked, artifact.quarantined, …) are also written to an append-only registry_events table.

Key events: RequirementCaptured, SpecCreated, SpecLocked, GateCompleted, BackendInvoked, PullRequestCreated, EvidenceFinalized, ApprovalRequested, ApprovalGranted


Exit codes

Code Meaning
0 success
1 generic failure
2 invalid usage/config
3 policy blocked
4 verification failed
5 dependency/tool unavailable
6 integration failure
7 authentication/authorization
8 spec drift
9 architecture violation
10 cancelled