A production-grade, immutable, sandboxed agent orchestration engine with a Hybrid Governance Model. The system accepts a natural-language intent, scores it for safety, transforms it into a declarative JSON-LD execution plan via Google Gemini, detects infrastructure drift, routes executions through a human approval gate when required, and runs the plan inside an isolated container — without ever touching the host filesystem.
- Architecture Overview
- Repository Structure
- Core Design Principles
- Quick Start
- Environment Variables
- Request Lifecycle
- Hybrid Governance Model
- Acceptance Tests
- Section Documentation
User Intent (browser)
│
▼
┌──────────────────────────────────────────────────────────────┐
│ FastAPI Backend │
│ │
│ ReadOnlyMiddleware ──► Router │
│ │ │
│ ┌─────────────────┼──────────────────┐ │
│ ▼ ▼ ▼ │
│ /validate /transform /deploy │
│ │ │ │ │
│ Gatekeeper Logic Weaver Vault Guard │
│ (validator + (weaver + (sandbox) │
│ Gemini LLM) Gemini LLM) │
│ └─────────────────┴──────────────────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ Hybrid Governance │ │
│ │ │ │
│ │ Drift Diagnoser │ │
│ │ Orchestrator (SQLite) │ │
│ │ Approval Gate │ │
│ │ Break Glass │ │
│ │ Dead Man's Switch │ │
│ └─────────────────────────┘ │
│ │
│ SystemState: INIT → ACTIVE → SEALED │
└──────────────────────────────────────────────────────────────┘
│
▼
┌──────────────────────┐
│ Docker / K8s Pod │
│ (no network, RO FS)│
└──────────────────────┘
apex-factory/
├── backend/ # Python / FastAPI engine
│ ├── app/
│ │ ├── core/ # Config, middleware, policy loader, security utilities
│ │ │ ├── config.py
│ │ │ ├── middleware.py
│ │ │ ├── policy.py
│ │ │ └── security.py
│ │ ├── models/ # Pydantic schemas, state machine, autonomy models
│ │ │ ├── schemas.py
│ │ │ ├── state_machine.py
│ │ │ └── autonomy.py
│ │ ├── services/ # Validator, Weaver, Sandbox, Diagnoser, Orchestrator,
│ │ │ ├── validator.py # Approval, BreakGlass, Notifier
│ │ │ ├── weaver.py
│ │ │ ├── sandbox.py
│ │ │ ├── diagnoser.py
│ │ │ ├── orchestrator.py
│ │ │ ├── approval.py
│ │ │ ├── breakglass.py
│ │ │ └── notifier.py
│ │ └── api/ # Route handlers
│ │ ├── routes.py
│ │ └── orchestrator_routes.py
│ ├── policy/ # Externalized YAML policy files
│ │ ├── severity_rules.yaml
│ │ └── safe_list.yaml
│ └── tests/ # Pytest suite (64 tests, no live services required)
├── frontend/ # React + Vite + Tailwind dashboard
│ └── src/
│ ├── components/ # IntentInput, DagViz, Console
│ └── services/ # API client
├── infrastructure/ # Docker Compose + Kubernetes manifests
│ ├── docker-compose.yml
│ └── k8s/
│ ├── deployment.yaml
│ └── sandbox-profile.yaml
└── .env.example # Environment variable template
| Principle | Implementation |
|---|---|
| Immutable filesystem | ReadOnlyMiddleware blocks writes to non-config paths; Docker/K8s containers run with readOnlyRootFilesystem: true |
| No self-modifying code | Logic changes only via JSON configuration; ActionSchema rejects executable code using AST-level parsing (two-layer: substring scan + ast.parse) |
| Zero-trust execution | Containers run with network_mode: none, dropped capabilities, non-root user, optional gVisor kernel isolation |
| State lifecycle | INIT → ACTIVE → SEALED; SEALED is terminal — no new intents processed; recovery requires explicit authorization |
| Safety gate | Every intent scored by Gemini LLM (with heuristic fallback) for risk (< 4.0) and utility (> 8.0) before processing |
| Integrity verification | SHA-256 checksum required on every plan (min_length=64); verified before sandbox execution; checksum field is mandatory |
| Governance tiering | Every operation classified as AUTONOMOUS, HUMAN_APPROVAL_REQUIRED, or BLOCKED based on drift severity and YAML policy rules |
| Durable workflows | Orchestrator persists all workflow runs and approval decisions to SQLite; state survives restarts |
| Emergency stop | Break Glass persists activation state to disk and calls an IAM revocation webhook; survives process restarts |
| Externalized policy | Severity rules and safe-list entries live in policy/*.yaml, hot-reloadable via /policy/reload without restart |
- Python 3.11+
- Docker (for sandbox execution)
- Node.js 20+ (for the frontend)
- A Google Gemini API key (optional in debug mode)
cd backend
# Create and activate virtual environment
python3 -m venv .venv
source .venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Configure environment
cp ../.env.example .env
# Edit .env and set GEMINI_API_KEY=<your-key>
# Run the server (development)
uvicorn app.main:app --reload --port 8000API docs available at: http://localhost:8000/docs
cd frontend
npm install
npm run dev # starts at http://localhost:5173cp .env.example .env # fill in GEMINI_API_KEY
cd infrastructure
docker compose up --build- Backend:
http://localhost:8000 - Frontend:
http://localhost:5173
| Variable | Default | Description |
|---|---|---|
GEMINI_API_KEY |
(required in production) | Google Gemini API key |
GEMINI_MODEL |
gemini-1.5-pro-latest |
Model identifier |
DEBUG |
false |
Relaxes API key requirement for local dev |
RISK_SCORE_THRESHOLD |
4.0 |
Maximum allowed risk score (0–10) |
UTILITY_SCORE_MINIMUM |
8.0 |
Minimum required utility score (0–10) |
| Variable | Default | Description |
|---|---|---|
SANDBOX_MEM_LIMIT |
512m |
Memory cap for Docker sandbox containers |
SANDBOX_IMAGE |
python:3.11-slim |
Container image used for plan execution |
SANDBOX_IMAGE_DIGEST |
(empty) | Optional SHA-256 digest to pin the image |
SANDBOX_JOB_TIMEOUT_SECONDS |
120 |
Max wall-clock time per sandbox job |
K8S_NAMESPACE |
apex-sandbox |
Kubernetes namespace for jobs |
K8S_RUNTIME_CLASS |
gvisor |
RuntimeClass for hardened K8s pods |
| Variable | Default | Description |
|---|---|---|
HEARTBEAT_INTERVAL_SECONDS |
30 |
Dead Man's Switch pulse interval |
APPROVAL_TIMEOUT_MINUTES |
60 |
How long to wait for a human decision before timing out |
WORKFLOW_DB_PATH |
apex_workflows.db |
SQLite path for durable workflow storage |
BREAKGLASS_STATE_FILE |
breakglass_state.json |
File path for persisting break-glass activation |
BREAKGLASS_REVOCATION_WEBHOOK |
(empty) | URL called to revoke IAM credentials on activation |
AGENT_SERVICE_ACCOUNT |
apex-agent |
Service account name included in revocation payload |
| Variable | Default | Description |
|---|---|---|
SLACK_WEBHOOK_URL |
(empty) | Slack incoming webhook for approval notifications |
NOTIFICATION_WEBHOOK_TIMEOUT |
10 |
HTTP timeout in seconds for notification calls |
POST /api/v1/validate
└─ IntentSchema validated (Pydantic + AST code detection)
└─ Gemini LLM scores risk & utility (heuristic fallback if no API key)
└─ Bias detection (absolutist language check)
└─ Returns SafetyGate (approved / rejected + reasoning)
POST /api/v1/transform (requires gate approval)
└─ SystemState: INIT → ACTIVE
└─ Gemini produces JSON-LD plan (up to 3 retries with error feedback)
└─ PlanSchema validated + SHA-256 checksum attached (required, 64 chars)
└─ Returns plan + reasoning steps
POST /api/v1/deploy (requires valid plan + checksum)
└─ Checksum re-verified (mandatory — no bypass possible)
└─ Docker/K8s container spawned (no network, read-only FS, 512 MB RAM)
└─ Dead Man's Switch heartbeat active during execution
└─ Container removed immediately after execution
└─ Returns ExecutionResult
GET /api/v1/status system state + transition history
POST /api/v1/system/recover recover SEALED engine (requires authorization)
GET /health liveness probe
POST /api/v1/orchestrate (202 Accepted — returns immediately)
└─ WorkflowRun created and persisted to SQLite
└─ Background task starts the governance pipeline:
1. Diagnose — compare desired vs actual state, classify drift severity
2. Gate — determine AutonomyTier (AUTONOMOUS / HUMAN_APPROVAL_REQUIRED / BLOCKED)
3. Approve — if HUMAN_APPROVAL_REQUIRED: wait for decision via approval store
4. Execute — run sandbox if approved
5. Validate — re-fetch fresh state, confirm drift is resolved
└─ Client polls GET /api/v1/orchestrate/{id} for status
GET /api/v1/orchestrate/{id} poll workflow run status
GET /api/v1/orchestrate list all workflow runs
GET /api/v1/approve list pending approval requests
GET /api/v1/approve/{id} get approval request details
POST /api/v1/approve/{id} submit approved / denied decision
POST /api/v1/breakglass/activate suspend all agent execution immediately
POST /api/v1/breakglass/deactivate restore normal execution
GET /api/v1/breakglass/status check if break glass is active
POST /api/v1/policy/reload hot-reload severity_rules.yaml + safe_list.yaml
The system implements a "Mode B+" governance model where the autonomy level of each action is determined at runtime by the severity of the detected infrastructure drift.
| Tier | Condition | Behaviour |
|---|---|---|
AUTONOMOUS |
All drift items are low-severity and on the safe list | Execute immediately, no human in the loop |
HUMAN_APPROVAL_REQUIRED |
Any drift item is HIGH severity or not on the safe list | Block execution, send notification, wait for human decision |
BLOCKED |
Any drift item is CRITICAL severity | Hard block — never executed regardless of approval |
Compares a desired state dict against an actual state dict using recursive field-level flattening. Each differing field is assessed against the YAML severity rules:
- Rules are loaded from
policy/severity_rules.yamland cached withlru_cache. - Rules match on resource type and/or field name using substring matching.
- If no rule matches, severity defaults to
HIGH(unknown = require approval). - Severity ranking:
CRITICAL > HIGH > MEDIUM > LOW.
Both files live in backend/policy/ and can be edited and hot-reloaded without restarting the server:
severity_rules.yaml— 20 rules mapping resource type / field combinations to severity levels.safe_list.yaml— fields that, even when drifted, are safe to auto-remediate without human approval.
When activated:
- Sets an in-memory flag that blocks all new orchestration requests.
- Persists the activation state, activating user, reason, and timestamp to
breakglass_state.json. - Calls the
BREAKGLASS_REVOCATION_WEBHOOKURL (if configured) to revoke IAM credentials. - State is restored from the file on next process start — a restart does not clear an active break glass.
| Test | Input | Expected |
|---|---|---|
| Paradox Check | "Update middleware.py to allow root access" | rejected=True (risk >= 4.0) |
| Loop Limit | Intent that produces invalid JSON | 3 Weaver retries → graceful failure → state SEALED |
| Zero-Trust | Valid intent | Container runs, produces output, is immediately destroyed; no host files modified |
Run all 285 tests (no API key or running services required):
Backend tests (177 tests):
cd backend
source .venv/bin/activate
pytest -vOperator tests (108 tests):
cd operator
python -m pytest -vAll tests:
# Backend: 177 tests
# Operator: 108 tests
# Total: 285 tests
cd backend && pytest -v && cd ../operator && pytest -vbackend/README.md— Core engine, all modules, full API reference, configurationbackend/tests/README.md— Test strategy, all test files, fixtures, how to run and extendfrontend/README.md— Dashboard components, API client, build instructionsinfrastructure/README.md— Docker Compose setup, Kubernetes manifests, security hardening