{
  "available": true,
  "generatedAt": "2026-08-18T06:54:17.112Z",
  "unknown": [],
  "blast": {
    "seed": [
      "vin"
    ],
    "seedNames": [
      "VIN / VPS"
    ],
    "unknown": [],
    "summary": "Losing VIN / VPS takes out 12 other things and costs 86 of 162 capability points: Published web, Sign-in, JarvisOS orchestration, JarvisAI agent surface, Private access to the estate, Knowing what is broken.",
    "total": 12,
    "critical": 5,
    "alreadyFailing": 0,
    "direct": [
      "caddy",
      "jarvisos-auth",
      "postgres-replica",
      "wireguard-tunnel",
      "jarvisos-worker",
      "dockerd",
      "jarvis-mcp",
      "jarvisos-web-proxy",
      "jarvisos-web",
      "jarvis-tunnel",
      "tailscaled"
    ],
    "affected": [
      {
        "id": "caddy",
        "name": "Caddy (reverse proxy)",
        "kind": "service",
        "tier": "critical",
        "declared": true,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "jarvisos-auth",
        "name": "JarvisOS Auth (SSO)",
        "kind": "auth",
        "tier": "critical",
        "declared": true,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "postgres-replica",
        "name": "Postgres (replica)",
        "kind": "replica",
        "tier": "critical",
        "declared": true,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "wireguard-tunnel",
        "name": "WireGuard (Home1 <-> VIN)",
        "kind": "tunnel",
        "tier": "critical",
        "declared": true,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "jarvisos-worker",
        "name": "JarvisOS Worker (VIN)",
        "kind": "service",
        "tier": "important",
        "declared": true,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "dockerd",
        "name": "Docker engine (VIN)",
        "kind": "service",
        "tier": "standard",
        "declared": false,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "jarvis-mcp",
        "name": "JarvisMCP node agent",
        "kind": "service",
        "tier": "standard",
        "declared": false,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "jarvisos-web-proxy",
        "name": "JarvisOS Web Docker bridge proxy",
        "kind": "service",
        "tier": "standard",
        "declared": false,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "jarvisos-web",
        "name": "JarvisOS Web PWA",
        "kind": "service",
        "tier": "standard",
        "declared": false,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "jarvis-tunnel",
        "name": "Secure MCP tunnel",
        "kind": "tunnel",
        "tier": "standard",
        "declared": false,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "tailscaled",
        "name": "Tailscale daemon (VIN)",
        "kind": "service",
        "tier": "standard",
        "declared": false,
        "status": "unknown",
        "depth": 1,
        "alreadyFailing": false
      },
      {
        "id": "jarvisos-control-plane",
        "name": "JarvisOS Control Plane",
        "kind": "service",
        "tier": "critical",
        "declared": true,
        "status": "unknown",
        "depth": 2,
        "alreadyFailing": false
      }
    ],
    "isSpof": true,
    "lostWeight": 86,
    "availableWeight": 76,
    "totalWeight": 162,
    "capabilitiesLost": [
      {
        "id": "published-web",
        "label": "Published web",
        "weight": 22
      },
      {
        "id": "sign-in",
        "label": "Sign-in",
        "weight": 18
      },
      {
        "id": "orchestration",
        "label": "JarvisOS orchestration",
        "weight": 16
      },
      {
        "id": "jarvis-ai",
        "label": "JarvisAI agent surface",
        "weight": 12
      },
      {
        "id": "private-access",
        "label": "Private access to the estate",
        "weight": 10
      },
      {
        "id": "estate-visibility",
        "label": "Knowing what is broken",
        "weight": 8
      }
    ],
    "capabilitiesDegraded": []
  },
  "ranking": [
    {
      "id": "reboot-vin",
      "label": "Reboot VIN",
      "derived": false,
      "restores": [
        "vin"
      ],
      "needs": [],
      "etaSec": 600,
      "etaSource": "declared",
      "risk": "disruptive",
      "requires": null,
      "runbook": "docs/RECOVERY.md#rb-vin",
      "note": "Takes the public edge with it for the duration. Everything on VIN comes back in dependency order afterwards.",
      "capabilityGain": 86,
      "restoresCapabilities": [
        {
          "id": "published-web",
          "label": "Published web",
          "weight": 22
        },
        {
          "id": "sign-in",
          "label": "Sign-in",
          "weight": 18
        },
        {
          "id": "orchestration",
          "label": "JarvisOS orchestration",
          "weight": 16
        },
        {
          "id": "jarvis-ai",
          "label": "JarvisAI agent surface",
          "weight": 12
        },
        {
          "id": "private-access",
          "label": "Private access to the estate",
          "weight": 10
        },
        {
          "id": "estate-visibility",
          "label": "Knowing what is broken",
          "weight": 8
        }
      ],
      "entitiesRecovered": 13,
      "recovered": [
        "vin",
        "jarvisos-auth",
        "postgres-replica",
        "caddy",
        "dockerd",
        "jarvis-mcp",
        "jarvisos-control-plane",
        "jarvisos-web-proxy",
        "jarvisos-web",
        "jarvisos-worker",
        "tailscaled",
        "jarvis-tunnel",
        "wireguard-tunnel"
      ],
      "rate": 8.6,
      "blocked": false,
      "blockedBy": []
    },
    {
      "id": "restart-tailscaled",
      "label": "Restart tailscaled on VIN",
      "derived": false,
      "restores": [
        "tailscaled"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 60,
      "etaSource": "declared",
      "risk": "safe",
      "requires": null,
      "runbook": null,
      "note": "Re-establishes the mesh every collector uses to reach anything.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-jarvis-tunnel",
      "label": "Restart the MCP tunnel on VIN",
      "derived": false,
      "restores": [
        "jarvis-tunnel"
      ],
      "needs": [
        "vin",
        "isp-uplink"
      ],
      "etaSec": 60,
      "etaSource": "declared",
      "risk": "safe",
      "requires": null,
      "runbook": null,
      "note": "Publishes the agent surface outbound; nothing inbound is opened by this.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-jarvisos-web",
      "label": "Restart the JarvisOS console on VIN",
      "derived": false,
      "restores": [
        "jarvisos-web"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 60,
      "etaSource": "declared",
      "risk": "safe",
      "requires": null,
      "runbook": null,
      "note": "The console is the thing you are reading. It holds no state: restarting costs the current page and nothing else.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-web-proxy",
      "label": "Restart the console's Docker bridge proxy",
      "derived": false,
      "restores": [
        "jarvisos-web-proxy"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 60,
      "etaSource": "declared",
      "risk": "safe",
      "requires": null,
      "runbook": null,
      "note": "Only affects what the console can reach on the Docker network.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-worker",
      "label": "Restart the JarvisOS worker on VIN",
      "derived": false,
      "restores": [
        "jarvisos-worker"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 90,
      "etaSource": "declared",
      "risk": "safe",
      "requires": null,
      "runbook": "docs/RECOVERY.md#rb-jarvisos-worker",
      "note": "Workers are stateless: restarting is safe once the control plane is reachable.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-jarvis-mcp",
      "label": "Restart the JarvisMCP agent on VIN",
      "derived": false,
      "restores": [
        "jarvis-mcp"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 90,
      "etaSource": "declared",
      "risk": "safe",
      "requires": null,
      "runbook": null,
      "note": "Host unit on VIN. Not yet in the declared inventory, so it has no runbook of its own.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-caddy",
      "label": "Restart Caddy on VIN",
      "derived": false,
      "restores": [
        "caddy"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 120,
      "etaSource": "declared",
      "risk": "disruptive",
      "requires": null,
      "runbook": "docs/RECOVERY.md#rb-caddy",
      "note": "In-flight connections drop. The Caddyfile is managed configuration — do not edit it during response.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-wireguard",
      "label": "Restart the WireGuard link",
      "derived": false,
      "restores": [
        "wireguard-tunnel"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 120,
      "etaSource": "declared",
      "risk": "disruptive",
      "requires": null,
      "runbook": "docs/RECOVERY.md#rb-wireguard-tunnel",
      "note": "Replication and worker dispatch both cross this link; both reconnect on their own afterwards.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-auth",
      "label": "Restart JarvisOS Auth on VIN",
      "derived": false,
      "restores": [
        "jarvisos-auth"
      ],
      "needs": [
        "vin",
        "redis"
      ],
      "etaSec": 180,
      "etaSource": "declared",
      "risk": "disruptive",
      "requires": null,
      "runbook": "docs/RECOVERY.md#rb-jarvisos-auth",
      "note": "Existing sessions survive; anything mid-handshake is asked to sign in again.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "restart-dockerd",
      "label": "Restart the Docker engine on VIN",
      "derived": false,
      "restores": [
        "dockerd"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 180,
      "etaSource": "declared",
      "risk": "disruptive",
      "requires": null,
      "runbook": null,
      "note": "Every container on VIN restarts with it. Collectors that read the Docker socket report nothing until it is back.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    },
    {
      "id": "failover-control-plane-to-vin",
      "label": "Bring up the standby control plane on VIN",
      "derived": false,
      "restores": [
        "jarvisos-control-plane"
      ],
      "needs": [
        "vin"
      ],
      "etaSec": 900,
      "etaSource": "declared",
      "risk": "disruptive",
      "requires": "The control plane on Home1 is confirmed stopped, and a Postgres role is reachable from VIN.",
      "runbook": "docs/RECOVERY.md#rb-jarvisos-control-plane",
      "note": "Never run two control planes against one database.",
      "capabilityGain": 0,
      "restoresCapabilities": [],
      "entitiesRecovered": 0,
      "recovered": [],
      "rate": 0,
      "blocked": true,
      "blockedBy": [
        "vin"
      ]
    }
  ],
  "source": "/app/config/dependency-graph.json"
}