Diagrams in diagrams/*.mmd (Mermaid, render natively on GitHub):
diagrams/architecture.mmd: System components, clients, pipeline, harness layers, and observability.diagrams/eval-pipeline.mmd: Case evaluation flow from benchmark YAML to gates, reports, and web UI.diagrams/trace-lifecycle.mmd: Sequence diagram of per-case execution, gateway mediation, and UI replay.diagrams/deployment-model.mmd: Local CLI, enterprise rootless Docker containers, and multi-OS CI matrix.diagrams/regression-flow.mmd: Decision flow for threshold gating and regression detection (fail closed).diagrams/security-model.mmd: Threat boundaries, injection detection, tool permissions, and network guard.diagrams/versioning-model.mmd: VersionBundle fingerprinting and drift detection across runs.CLI (cli/) ── pytest bridge (pytest_plugin.py) ── Web Dashboard (web/server.py)
│
Operations & Commands: run / ablate / calibrate / repro / regression / compare / status / serve
│
Runner (runner/) ── Benchmark Registry (registry/) ── Datasets (datasets/*.jsonl)
│ per case: fresh Environment
Harness (harness/) = Execution Environment
├─ ToolGateway (permissions, validation, limits, retries, fault injection)
├─ VerificationLayer (output/arg checks, retry orchestration) [ablatable]
├─ ContextOptimizer (observation trimming/dedup) [ablatable]
└─ ResourceGuards (steps, tool calls, wall clock, output/state bytes, network)
Agents (agents/) = unit under test
├─ ModelBackend protocol ── ScriptedModel (deterministic) | LiveBackends
├─ 5 pattern agents (ReAct, Plan-Execute, Supervisor, Swarm, Map-Reduce)
└─ Adapters (LangGraph / OpenAI Agents SDK / CrewAI)
Evaluators (evaluators/) = deterministic + llm_judge + trajectory
Metrics (metrics/) → Comparison (comparison/) → Regression engine (regression/)
Reporting (reporting/) = Markdown + JSON + Web UI ← Observability event stream (observability/)
Security (security/) = policy, injection screen, redaction, network guard, audit
Deployment (infra/) = Dockerfile (multi-stage, non-root) + docker-compose (runner/dashboard/status)
RunContext (gateway + events +
model backend + limits). Every decision/tool call/state change emits an event.AgentAdapter.run(ctx) -> AgentRunOutcome — framework-agnostic entry.ModelBackend.decide(state) -> ModelDecision — Think |
Plan | ToolCallDecision |
| Handoff | FinalAnswer | Malformed. |
Evaluator.evaluate(case, result) -> EvaluationResult — name, version, score [0,1],
passed, details, error.AblationProfile — flags {verification, retry, tool_validation, context_optimization}.FailureClass — NONE |
TEST_FAILURE | AGENT_ERROR | EVALUATOR_ERROR | INFRASTRUCTURE_FAILURE |
| SECURITY_VIOLATION | TIMEOUT | STEP_LIMIT | TOOL_LIMIT | LOOP_DETECTED. |
VersionBundle — agent/model/harness/benchmark/dataset(+sha256)/evaluator/prompt/
environment versions recorded in every run manifest.Belt-and-suspenders: (a) tools are offline fixtures by construction; (b) tool allowlist + forbidden-arg guards at the gateway; (c) socket guard raises SecurityViolation if anything opens a network socket during a run; (d) injection screening flags adversarial text in tasks and tool outputs (audit-logged, never silently dropped); (e) secret redaction at export; (f) resource caps bound worst case; (g) audit JSONL; (h) production container runs as non-root user (UID 10001). Arbitrary user agent code is explicitly OUT of the sandbox threat boundary in v0.1 (documented in THREAT-MODEL.md §trust boundaries).
--model spec.web/server.py or consume REST JSON via /api/runs.