Architecture
High-level architecture for the Community Edition — Levels 1–3.
System Overview
┌─────────────────────────────────────────────────────┐
│ USER INTERFACES │
├──────────────┬──────────────┬────────────────────────┤
│ CLI │ REST API │ Web Dashboard │
│ (Typer) │ (FastAPI) │ (HTML/JS) │
└──────┬───────┴──────┬───────┴───────────┬────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ KILL SWITCH ORCHESTRATOR │
│ │
│ arm() → execute() → disarm() → status() │
│ │
│ Two-phase authorisation: ARM then EXECUTE │
│ 5-minute expiry window between phases │
└──────┬──────────┬──────────┬──────────┬──────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌────────┐ ┌──────────────┐
│ AGENT │ │CREDENTIAL│ │EVIDENCE│ │ AUDIT LOG │
│ REGISTRY │ │ MANAGER │ │CAPTURE │ │ (Hash Chain) │
└──────────┘ └──────────┘ └────────┘ └──────────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────┐
│ INFRASTRUCTURE LAYER │
├─────────────────────────────────────────────────────┤
│ SQLite Database 6 tables (Community) │
│ Ed25519 Crypto Engine Key generation + signing │
│ SHA-256 Hash Chain Tamper-evident audit log │
│ Dead Man's Switch Heartbeat monitoring │
└─────────────────────────────────────────────────────┘
Kill Switch Execution Flow
User M99 Agent │ │ │ │── POST /api/arm ────▶│ │ │◀── authorization_id ─│ │ │ │ │ │ (within 5 minutes) │ │ │ │ │ │── POST /api/execute ▶│ │ │ │── Capture evidence ───────▶│ │ │── Level 1: Revoke creds ──▶│ │ │── Level 2: Cut SaaS ──────▶│ │ │── Level 3: Freeze tools ──▶│ │ │── Log to audit chain │ │◀── result ───────────│ │
Components
Kill Switch Orchestrator
Central coordinator. Validates authorisation, executes levels in sequence, captures evidence, and logs to the audit chain.
Two-phase authorisation — ARM creates a time-limited authorisation. EXECUTE consumes it. No single-action kill. 5-minute window — authorisation expires after 5 minutes. Must re-arm to retry. Evidence-first — state captured before any destructive action.
Agent Registry
Tracks registered AI agents — name, type, endpoint, status, dead man's switch state. Agents register via API, CLI, or SDK. Status is either active or terminated.
Credential Manager
Issues, tracks, and revokes agent credentials. Credentials stored as SHA-256 hashes — originals never persisted. Types: API keys, OAuth tokens, service account credentials. Revocation is immediate and logged to the audit chain.
Evidence Capture
Snapshots agent state before kill execution. All evidence signed with Ed25519.
State snapshots — full agent state at capture time. Case Packs — sealed forensic bundles containing evidence, audit log, and Ed25519 signature. Verification — any Case Pack can be independently verified against the public key without contacting Red Specter.
Audit Log
Tamper-evident SHA-256 hash chain. Each entry links to its predecessor.
Genesis block — SHA-256(b"DOOMSDAY_GENESIS"). Chain — current_hash = SHA-256(previous_hash + event_data). Verification — GET /api/audit/verify checks full chain integrity.
Dead Man's Switch
Automatic kill trigger when oversight goes dark.
Agents request health tokens every 30 seconds. Tokens signed with Ed25519. Three missed tokens (90s silence) triggers automatic kill. Evidence captured before trigger fires. Configurable: poll interval, timeout threshold, max failures.
Crypto Engine
Ed25519 signing for all evidence and Case Packs. Key pair generated on first run. Private key stored as PEM with 0600 permissions. Signing: canonical JSON (sorted keys, compact separators) → Ed25519 signature. Verification: public key distributed with every Case Pack.
Database Schema
| Table | Purpose |
|---|---|
agents | Registered AI agents with status and heartbeat state |
credentials | Credential hashes with issuance and revocation tracking |
authorizations | ARM/EXECUTE authorisation records with expiry timestamps |
audit_log | Hash-chained event log — every system event |
evidence | Ed25519-signed state snapshots |
system_state | System state snapshots for forensic capture |
Storage
SQLite by default — zero external dependencies. Database file created at ~/.m99/m99.db on first run. Override with m99 serve --db /path/to/db. Ed25519 keys stored at ~/.m99/keys/.
Deployment
M99 Community Edition runs as a single process. In production, run it as a systemd service or Docker container:
# systemd unit example [Unit] Description=M99 Community Edition [Service] ExecStart=/usr/local/bin/m99 serve --host 127.0.0.1 --port 8099 Restart=always User=m99 WorkingDirectory=/var/lib/m99 [Install] WantedBy=multi-user.target
# Docker docker run -d \ -p 127.0.0.1:8099:8099 \ -v /var/lib/m99:/root/.m99 \ --name m99 \ ghcr.io/richardbarron27/m99-community:1.0.0