🚀

AI Agent Deployment Readiness Scorecard

Score production readiness across 8 dimensions. Pick a scenario, check the items you have in place, and get a verdict plus open P0 list.

1. Pick a deployment scenario

Scores are directional estimates based on common production-readiness practices. A passing score does not replace legal, security, or compliance review before launch.

How the score is calculated

  • Scenario filters the checklist to the checks that matter for your blast radius.
  • P0 items are weighted 3×. P1 items are weighted 2×. Other items are weighted 1×.
  • Open P0s are shown explicitly because they are launch blockers.
  • Top gap is the dimension with the lowest completion rate.

Next steps

Frequently asked questions

What score is considered production-ready?

A score of 90% or higher with zero open P0 items is treated as production ready. Between 75% and 89% is a launch candidate with a feature-flag or limited rollout. Below 75% the tool recommends closing gaps before exposing the agent to real traffic.

Which dimensions matter most for customer-facing agents?

Architecture, privacy/security, reliability, and observability carry the most weight. Model choice and fallback, error handling, rate-limit backoff, structured logging, and a clear rollback plan are treated as P0 items.

How is this different from a security audit?

This scorecard is a self-service readiness screen, not a replacement for a legal, compliance, or penetration test. Use it to identify gaps before scheduling deeper reviews.

Can I use this for internal-only agents?

Yes. The scenario selector scales the checklist to match blast radius. Internal tools and MVP prototypes skip many customer-facing and regulated-industry items.

🤖 Use this tool in your agent

✓ Agent-ready code

Copy the snippet below into your agent, newsletter, or script. The tool page at hermesdispatch.dev/tools/agent-deployment-scorecard/ is the canonical contract: inputs, outputs, and formulas.

python
# Hermes Dispatch Tool — AI Agent Deployment Readiness Scorecard
# Source: https://hermesdispatch.dev/tools/agent-deployment-scorecard/
# Description: Score AI agent production readiness by launch type, region, data sensitivity, SLA, and latency target.
# License: MIT (generated by hermesdispatch.dev)
#
# INSTALL:
#   1. Save this file as ~/.hermes/hermes-agent/tools/agent_deployment_scorecard.py
#   2. Restart Hermes or run /reset in a session
#   3. The tool auto-registers if Hermes uses auto-discovery of tools/*.py
#
# MANUAL REGISTRY (if auto-discovery is off):
#   from tools.agent_deployment_scorecard import register
#   register()

import json

DATA = {"last_updated": "2026-07-04", "note": "Readiness scores are directional. Use this scorecard to surface blockers before launch, not as a substitute for a full security, legal, or compliance review.", "launch_types": [{"slug": "prototype", "name": "Prototype / demo", "description": "Internal demo or limited alpha. Lower reliability and compliance expectations."}, {"slug": "beta", "name": "Closed beta", "description": "Invite-only beta with real user data. Need basic privacy, observability, and incident response."}, {"slug": "production", "name": "Production launch", "description": "Public or paid launch. Requires full security, SLA, compliance, and cost controls."}], "regions": [{"slug": "us", "name": "United States", "frameworks": ["CCPA/CPRA", "SOC 2"]}, {"slug": "eu", "name": "EU / EEA", "frameworks": ["GDPR", "EU AI Act", "NIS2"]}, {"slug": "uk", "name": "United Kingdom", "frameworks": ["UK GDPR", "Data Protection Act"]}, {"slug": "ca", "name": "Canada", "frameworks": ["PIPEDA"]}, {"slug": "au", "name": "Australia", "frameworks": ["Privacy Act"]}, {"slug": "global", "name": "Global launch", "frameworks": ["GDPR", "CCPA/CPRA", "EU AI Act"]}], "data_sensitivity": [{"slug": "public", "name": "Public web / no PII", "risk": 1}, {"slug": "general", "name": "General business data", "risk": 2}, {"slug": "pii", "name": "General PII", "risk": 3}, {"slug": "sensitive", "name": "Health, financial, or biometric", "risk": 5}, {"slug": "children", "name": "Children's data", "risk": 5}], "dimensions": [{"slug": "architecture", "name": "Architecture & scope", "weight": 15, "questions": [{"id": "arch_scope", "text": "Use case, success criteria, and failure modes are documented.", "points": 3}, {"id": "arch_personas", "text": "Human-in-the-loop boundaries and escalation paths are defined.", "points": 3}, {"id": "arch_limit", "text": "Rate limits, concurrency caps, and cost kill-switches are configured.", "points": 3}, {"id": "arch_undo", "text": "Agent actions can be paused, rolled back, or manually approved.", "points": 3}, {"id": "arch_multi", "text": "Multi-region or failover strategy is planned if production.", "points": 3}]}, {"slug": "model", "name": "Model & provider", "weight": 15, "questions": [{"id": "model_provider", "text": "Primary and fallback LLM providers are chosen.", "points": 3}, {"id": "model_version", "text": "Model versions are pinned and upgrade policy is documented.", "points": 3}, {"id": "model_latency", "text": "P50/P95 latency targets are set and validated.", "points": 3}, {"id": "model_eval", "text": "Evaluation dataset or benchmark is run before each release.", "points": 3}, {"id": "model_jailbreak", "text": "Prompt injection / jailbreak mitigations are in place.", "points": 3}]}, {"slug": "data", "name": "Data & privacy", "weight": 15, "questions": [{"id": "data_inventory", "text": "Data types processed by the agent are inventoried.", "points": 3}, {"id": "data_retention", "text": "Retention and deletion policies are configured.", "points": 3}, {"id": "data_consent", "text": "User consent or lawful basis is documented.", "points": 3}, {"id": "data_dsr", "text": "Access / deletion / portability requests can be fulfilled.", "points": 3}, {"id": "data_crossborder", "text": "Cross-border transfers and DPA/subprocessors are reviewed.", "points": 3}]}, {"slug": "security", "name": "Security", "weight": 15, "questions": [{"id": "sec_keys", "text": "API keys and secrets are not hardcoded; use a secrets manager.", "points": 3}, {"id": "sec_auth", "text": "Authentication and authorization are enforced.", "points": 3}, {"id": "sec_input", "text": "User inputs are validated and sanitized.", "points": 3}, {"id": "sec_output", "text": "LLM outputs are filtered before acting on external systems.", "points": 3}, {"id": "sec_audit", "text": "Audit logs of agent decisions and tool calls are retained.", "points": 3}]}, {"slug": "reliability", "name": "Reliability & resilience", "weight": 15, "questions": [{"id": "rel_errors", "text": "Retry, timeout, and circuit-breaker patterns are implemented.", "points": 3}, {"id": "rel_sla", "text": "Uptime target is set and provider SLAs are reviewed.", "points": 3}, {"id": "rel_dr", "text": "Incident response / escalation runbook exists.", "points": 3}, {"id": "rel_backup", "text": "Critical state and vector stores are backed up.", "points": 3}, {"id": "rel_canary", "text": "Canary or staged rollout process is in place.", "points": 3}]}, {"slug": "observability", "name": "Observability", "weight": 10, "questions": [{"id": "obs_traces", "text": "Traces or logs capture request \u2192 model \u2192 tool flow.", "points": 3}, {"id": "obs_metrics", "text": "Key metrics (latency, cost, errors, quality) are tracked.", "points": 3}, {"id": "obs_alerts", "text": "Alerts exist for error spikes, cost spikes, and SLA breaches.", "points": 2}, {"id": "obs_eval", "text": "Periodic quality / drift evaluation is scheduled.", "points": 2}]}, {"slug": "cost", "name": "Cost & monetization", "weight": 10, "questions": [{"id": "cost_budget", "text": "Monthly LLM, hosting, and infra budget is set.", "points": 3}, {"id": "cost_per_request", "text": "Cost per request / per user is estimated.", "points": 3}, {"id": "cost_capping", "text": "Spend caps or quotas are configured with alerts.", "points": 2}, {"id": "cost_pricing", "text": "Pricing model (free, usage-based, seat) is defined.", "points": 2}]}, {"slug": "golive", "name": "Go-live plan", "weight": 5, "questions": [{"id": "go_checklist", "text": "Launch checklist is signed off by owner.", "points": 2}, {"id": "go_comm", "text": "User communication and rollback plan are ready.", "points": 2}, {"id": "go_support", "text": "Support / feedback channel is set up.", "points": 1}]}], "maturity_levels": [{"min": 0, "max": 39, "name": "Experiment", "color": "red", "summary": "Not launch-ready. Core gaps in architecture, security, or cost control."}, {"min": 40, "max": 59, "name": "Internal prototype", "color": "orange", "summary": "Safe for internal demos. Needs hardening before any real users or data."}, {"min": 60, "max": 79, "name": "Closed beta ready", "color": "yellow", "summary": "Ready for limited beta with known guardrails and close monitoring."}, {"min": 80, "max": 94, "name": "Production ready", "color": "green", "summary": "Ready for public or paid launch with normal operational oversight."}, {"min": 95, "max": 100, "name": "Enterprise ready", "color": "cyan", "summary": "Strong controls across all dimensions; suitable for high-stakes deployments."}], "risk_levels": [{"max": 5, "name": "Low", "summary": "Limited blast radius. Standard precautions are sufficient."}, {"max": 12, "name": "Moderate", "summary": "Real user or business impact possible. Address top blockers before launch."}, {"max": 20, "name": "High", "summary": "Significant compliance, financial, or reputational risk. Full review required."}, {"max": 100, "name": "Critical", "summary": "Do not launch without executive, legal, and security sign-off."}], "defaults": {"launch_type": "production", "region": "us", "data_sensitivity": "general", "monthly_requests": 100000, "sla_target": 99.9, "latency_p95_ms": 2000}}

def _ok(result):
    return json.dumps({"success": True, "data": result}, indent=2)

def _err(message):
    return json.dumps({"success": False, "error": message}, indent=2)


TOOL_NAME = "agent_deployment_scorecard"
TOOLSET = "agents"

SCHEMA = {
  "type": "function",
  "function": {
    "name": "agent_deployment_scorecard",
    "description": "Score AI agent production readiness by launch type, region, data sensitivity, SLA, and latency target.",
    "parameters": {
      "type": "object",
      "properties": {
        "launch_type": {
          "type": "string",
          "description": "Launch slug: prototype, beta, production"
        },
        "region": {
          "type": "string",
          "description": "Region slug: us, eu, uk, ca, au, global"
        },
        "data_sensitivity": {
          "type": "string",
          "description": "Sensitivity slug: public, general, pii, sensitive, children"
        },
        "expected_traffic_qps": {
          "type": "integer",
          "description": "Expected queries per second."
        },
        "sla_target": {
          "type": "number",
          "description": "Target uptime percentage."
        },
        "latency_target_ms": {
          "type": "number",
          "description": "P50 latency target in ms."
        }
      },
      "required": []
    }
  }
}

def _run(args):
    launch_type = args.get("launch_type", DATA["defaults"].get("launch_type", "internal"))
    region = args.get("region", DATA["defaults"].get("region", "us"))
    sensitivity = args.get("data_sensitivity", DATA["defaults"].get("data_sensitivity", "public"))
    traffic = int(args.get("expected_traffic_qps", DATA["defaults"].get("expected_traffic_qps", 1)))
    sla = float(args.get("sla_target", DATA["defaults"].get("sla_target", 99.9)))
    latency = float(args.get("latency_target_ms", DATA["defaults"].get("latency_target_ms", 2000)))
    lt = next((x for x in DATA["launch_types"] if x["slug"] == launch_type), DATA["launch_types"][0])
    reg = next((x for x in DATA["regions"] if x["slug"] == region), DATA["regions"][0])
    ds = next((x for x in DATA["data_sensitivity"] if x["slug"] == sensitivity), DATA["data_sensitivity"][0])
    base_risk = lt.get("risk_weight", 1) + reg.get("risk_weight", 0) + ds.get("risk_weight", 0)
    if sla >= 99.99:
        base_risk += 2
    if latency < 500:
        base_risk += 1
    if traffic > 100:
        base_risk += 1
    risk_level = next((r for r in DATA["risk_levels"] if r["min_score"] <= base_risk <= r["max_score"]), DATA["risk_levels"][-1])
    return _ok({
        "launch_type": lt["name"],
        "region": reg["name"],
        "data_sensitivity": ds["name"],
        "risk_level": risk_level["label"],
        "risk_score": base_risk,
        "top_dimensions": [d["name"] for d in DATA["dimensions"][:3]],
        "next_steps": ["Complete missing dimension checks", "Run latency budget calculator", "Set observability and alerting"]
    })

def HANDLER(args):
    try:
        return _run(args)
    except Exception as e:
        return _err(str(e))


def register():
    """Manual registry hook. Import and call this to register with Hermes."""
    try:
        from tools.registry import registry
        registry.register(
            name=TOOL_NAME,
            toolset=TOOLSET,
            schema=SCHEMA,
            handler=HANDLER,
        )
    except ImportError:
        print("Hermes registry not found; skipping manual registration.")

if __name__ == "__main__":
    # CLI smoke test
    print(HANDLER({}))

Want early access to the next locked tool? Subscribe to The Hermes Dispatch.

🚀 Get AI automation insights daily

15:00 MST. One-click unsubscribe.

Subscribe