{
  "available": true,
  "generatedAt": "2026-08-18T06:53:53.704Z",
  "policy": {
    "sources": "Edges come from three layers: the declared inventory (dependsOn and the host a thing runs on), the curated catalogue in config/discovery.json, and what collectors actually observed — a reverse-proxy route dialing a published port is a dependency whether or not anybody wrote it down. Where layers agree the edge is corroborated; where only one speaks, the edge names it.",
    "overrides": "The manual layer below is for edges nothing can observe, edges a collector gets wrong, and redundancy — the statement that any one of several things will do. Every entry carries a reason and the date somebody last checked it. Past evidenceMaxDays it is reported as stale evidence, exactly like an old collector reading, because an override nobody has re-read is not knowledge.",
    "closure": "A capability names only its entry points. Everything those rest on is computed, so a capability does not have to list the uplink, the host and the DNS zone to depend on them. Adding a dependency to the inventory therefore widens every capability that transitively reaches it, with no edit here.",
    "roles": "Ids are roles, not machines. \"postgres-primary\" is whichever instance is serving writes; promoting the replica restores that role on another node, which is why the promotion action restores postgres-primary rather than inventing a second id for the same job.",
    "weights": "Weight is how much of the estate's usefulness a capability represents, set by the operator. It is only ever compared with other weights here: it ranks recovery work, it does not measure anything about the world.",
    "ranking": "Recovery actions are ranked by capability returned per minute, not by size. Actions are worked in sequence, so a two-minute restart that returns sign-in belongs before a forty-minute rebuild that returns more — doing the small one first costs the big one nothing.",
    "rollback": "Delete config/dependency-graph.json. The console reports the graph as unloaded, the /graph page says so, and nothing else changes: incidents, recovery tasks and the catalogue do not depend on it."
  },
  "summary": {
    "nodes": 26,
    "declaredNodes": 20,
    "catalogueOnlyNodes": 6,
    "edges": 35,
    "edgesByOrigin": {
      "declared": 24,
      "curated": 6,
      "override": 5
    },
    "staleEdges": 0,
    "corroboratedEdges": 14,
    "overrides": 5,
    "suppressions": 0,
    "redundancyGroups": 1,
    "capabilities": 12,
    "capabilitiesLost": 0,
    "capabilitiesDegraded": 0,
    "totalWeight": 162,
    "availableWeight": 162,
    "spofs": 17,
    "criticalSpofs": 12,
    "spofsWithoutAction": 3,
    "actions": 21,
    "findings": {
      "crit": 0,
      "warn": 4,
      "info": 3
    }
  },
  "capabilities": [
    {
      "id": "published-web",
      "label": "Published web",
      "blurb": "Every hostname this estate answers on, from outside the house.",
      "weight": 22,
      "impact": "Noticed within seconds by anyone using anything. This is what 'the estate is down' means to a human.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "sign-in",
      "label": "Sign-in",
      "blurb": "Issuing and validating sessions for everything behind SSO.",
      "weight": 18,
      "impact": "An auth outage looks like a total outage: the services are up and nobody can reach them.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "orchestration",
      "label": "JarvisOS orchestration",
      "blurb": "Accepting, scheduling and dispatching work across the fleet.",
      "weight": 16,
      "impact": "Running work continues; nothing new starts. Noticed at the next dispatch rather than immediately.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "jarvis-ai",
      "label": "JarvisAI agent surface",
      "blurb": "The MCP agent on VIN and the tunnel that publishes it.",
      "weight": 12,
      "impact": "Assistant-driven work stops. Nothing else notices.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "data-writes",
      "label": "Data writes",
      "blurb": "The Postgres role that accepts writes.",
      "weight": 20,
      "impact": "Immediate and total for anything stateful. Recoverable only by promotion, which is one-way.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "data-reads",
      "label": "Data reads",
      "blurb": "Reading the system of record, from either the primary or the streaming replica.",
      "weight": 14,
      "impact": "Survives the loss of the home rack, which is the whole reason the replica exists.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "backups",
      "label": "On-site backups",
      "blurb": "The NAS dataset every backup lands in.",
      "weight": 12,
      "impact": "Nothing breaks today; the estate silently stops being recoverable. The worst failure mode here.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "offsite-recovery",
      "label": "Offsite recovery",
      "blurb": "The offsite copy that survives losing the home rack entirely.",
      "weight": 10,
      "impact": "Invisible until the day the house is the incident.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "public-names",
      "label": "Public name resolution",
      "blurb": "Cloudflare DNS: turning published hostnames into an address.",
      "weight": 14,
      "impact": "Looks exactly like a total outage from outside, and clients cache the failure.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "internal-names",
      "label": "Internal name resolution",
      "blurb": "Resolving estate names on the LAN.",
      "weight": 6,
      "impact": "Home1 clients lose names; the secondary resolver on VIN answers automatically.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "private-access",
      "label": "Private access to the estate",
      "blurb": "Reaching nodes without going through anything published — the tailnet, or the WireGuard link.",
      "weight": 10,
      "impact": "Losing both is what turns a service incident into 'nobody can get in to fix it'.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    },
    {
      "id": "estate-visibility",
      "label": "Knowing what is broken",
      "blurb": "This console: status, incidents, recovery tasks and the catalogue.",
      "weight": 8,
      "impact": "Everything still works and nobody can see it. Recovery becomes guesswork.",
      "available": true,
      "degraded": false,
      "lostVia": [],
      "degradedVia": []
    }
  ],
  "live": {
    "roots": [],
    "down": [],
    "lost": [],
    "degraded": [],
    "lostWeight": 0,
    "availableWeight": 162,
    "totalWeight": 162
  },
  "spofs": [
    {
      "id": "isp-uplink",
      "name": "ISP Uplink",
      "kind": "dependency",
      "tier": "critical",
      "declared": true,
      "external": true,
      "status": "unknown",
      "affected": 11,
      "criticalAffected": 8,
      "lostWeight": 90,
      "capabilities": [
        {
          "id": "published-web",
          "label": "Published web",
          "weight": 22
        },
        {
          "id": "sign-in",
          "label": "Sign-in",
          "weight": 18
        },
        {
          "id": "orchestration",
          "label": "JarvisOS orchestration",
          "weight": 16
        },
        {
          "id": "offsite-recovery",
          "label": "Offsite recovery",
          "weight": 10
        },
        {
          "id": "public-names",
          "label": "Public name resolution",
          "weight": 14
        },
        {
          "id": "private-access",
          "label": "Private access to the estate",
          "weight": 10
        }
      ],
      "actions": []
    },
    {
      "id": "vin",
      "name": "VIN / VPS",
      "kind": "node",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 12,
      "criticalAffected": 5,
      "lostWeight": 86,
      "capabilities": [
        {
          "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
        }
      ],
      "actions": [
        {
          "id": "reboot-vin",
          "label": "Reboot VIN",
          "etaSec": 600,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "home1",
      "name": "Home1",
      "kind": "node",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 6,
      "criticalAffected": 3,
      "lostWeight": 60,
      "capabilities": [
        {
          "id": "sign-in",
          "label": "Sign-in",
          "weight": 18
        },
        {
          "id": "orchestration",
          "label": "JarvisOS orchestration",
          "weight": 16
        },
        {
          "id": "data-writes",
          "label": "Data writes",
          "weight": 20
        },
        {
          "id": "internal-names",
          "label": "Internal name resolution",
          "weight": 6
        }
      ],
      "actions": [
        {
          "id": "restore-home1",
          "label": "Restore power and boot Home1",
          "etaSec": 1800,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "cloudflare-dns",
      "name": "Public DNS",
      "kind": "dns",
      "tier": "critical",
      "declared": true,
      "external": true,
      "status": "unknown",
      "affected": 1,
      "criticalAffected": 1,
      "lostWeight": 36,
      "capabilities": [
        {
          "id": "published-web",
          "label": "Published web",
          "weight": 22
        },
        {
          "id": "public-names",
          "label": "Public name resolution",
          "weight": 14
        }
      ],
      "actions": [
        {
          "id": "repoint-public-dns",
          "label": "Re-point the public DNS records",
          "etaSec": 1800,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "google-oauth",
      "name": "Google OAuth",
      "kind": "dependency",
      "tier": "critical",
      "declared": true,
      "external": true,
      "status": "unknown",
      "affected": 3,
      "criticalAffected": 2,
      "lostWeight": 34,
      "capabilities": [
        {
          "id": "sign-in",
          "label": "Sign-in",
          "weight": 18
        },
        {
          "id": "orchestration",
          "label": "JarvisOS orchestration",
          "weight": 16
        }
      ],
      "actions": []
    },
    {
      "id": "redis",
      "name": "Redis (cache / queue)",
      "kind": "database",
      "tier": "important",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 3,
      "criticalAffected": 2,
      "lostWeight": 34,
      "capabilities": [
        {
          "id": "sign-in",
          "label": "Sign-in",
          "weight": 18
        },
        {
          "id": "orchestration",
          "label": "JarvisOS orchestration",
          "weight": 16
        }
      ],
      "actions": [
        {
          "id": "restart-redis",
          "label": "Restart Redis on Home1",
          "etaSec": 120,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "jarvisos-auth",
      "name": "JarvisOS Auth (SSO)",
      "kind": "auth",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 2,
      "criticalAffected": 1,
      "lostWeight": 34,
      "capabilities": [
        {
          "id": "sign-in",
          "label": "Sign-in",
          "weight": 18
        },
        {
          "id": "orchestration",
          "label": "JarvisOS orchestration",
          "weight": 16
        }
      ],
      "actions": [
        {
          "id": "restart-auth",
          "label": "Restart JarvisOS Auth on VIN",
          "etaSec": 180,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "nas",
      "name": "NAS",
      "kind": "node",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 3,
      "criticalAffected": 2,
      "lostWeight": 22,
      "capabilities": [
        {
          "id": "backups",
          "label": "On-site backups",
          "weight": 12
        },
        {
          "id": "offsite-recovery",
          "label": "Offsite recovery",
          "weight": 10
        }
      ],
      "actions": [
        {
          "id": "restore-nas",
          "label": "Bring the NAS back",
          "etaSec": 3600,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "nas-backups",
      "name": "NAS backup dataset",
      "kind": "storage",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 1,
      "criticalAffected": 1,
      "lostWeight": 22,
      "capabilities": [
        {
          "id": "backups",
          "label": "On-site backups",
          "weight": 12
        },
        {
          "id": "offsite-recovery",
          "label": "Offsite recovery",
          "weight": 10
        }
      ],
      "actions": [
        {
          "id": "remount-nas-backups",
          "label": "Bring the backup dataset back online",
          "etaSec": 900,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "caddy",
      "name": "Caddy (reverse proxy)",
      "kind": "service",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 0,
      "criticalAffected": 0,
      "lostWeight": 22,
      "capabilities": [
        {
          "id": "published-web",
          "label": "Published web",
          "weight": 22
        }
      ],
      "actions": [
        {
          "id": "restart-caddy",
          "label": "Restart Caddy on VIN",
          "etaSec": 120,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "postgres-primary",
      "name": "Postgres (primary)",
      "kind": "database",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 0,
      "criticalAffected": 0,
      "lostWeight": 20,
      "capabilities": [
        {
          "id": "data-writes",
          "label": "Data writes",
          "weight": 20
        }
      ],
      "actions": [
        {
          "id": "promote-postgres-replica",
          "label": "Promote the Postgres replica on VIN",
          "etaSec": 900,
          "risk": "destructive"
        }
      ]
    },
    {
      "id": "jarvisos-control-plane",
      "name": "JarvisOS Control Plane",
      "kind": "service",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 1,
      "criticalAffected": 0,
      "lostWeight": 16,
      "capabilities": [
        {
          "id": "orchestration",
          "label": "JarvisOS orchestration",
          "weight": 16
        }
      ],
      "actions": [
        {
          "id": "failover-control-plane-to-vin",
          "label": "Bring up the standby control plane on VIN",
          "etaSec": 900,
          "risk": "disruptive"
        }
      ]
    },
    {
      "id": "jarvis-mcp",
      "name": "JarvisMCP node agent",
      "kind": "service",
      "tier": "standard",
      "declared": false,
      "external": false,
      "status": "unknown",
      "affected": 0,
      "criticalAffected": 0,
      "lostWeight": 12,
      "capabilities": [
        {
          "id": "jarvis-ai",
          "label": "JarvisAI agent surface",
          "weight": 12
        }
      ],
      "actions": [
        {
          "id": "restart-jarvis-mcp",
          "label": "Restart the JarvisMCP agent on VIN",
          "etaSec": 90,
          "risk": "safe"
        }
      ]
    },
    {
      "id": "gwscli-s3",
      "name": "GWSCLI / S3",
      "kind": "node",
      "tier": "important",
      "declared": true,
      "external": true,
      "status": "unknown",
      "affected": 1,
      "criticalAffected": 1,
      "lostWeight": 10,
      "capabilities": [
        {
          "id": "offsite-recovery",
          "label": "Offsite recovery",
          "weight": 10
        }
      ],
      "actions": []
    },
    {
      "id": "gwscli-s3-offsite",
      "name": "Offsite backup replica",
      "kind": "replica",
      "tier": "critical",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 0,
      "criticalAffected": 0,
      "lostWeight": 10,
      "capabilities": [
        {
          "id": "offsite-recovery",
          "label": "Offsite recovery",
          "weight": 10
        }
      ],
      "actions": [
        {
          "id": "rerun-offsite-sync",
          "label": "Re-run the offsite sync",
          "etaSec": 2400,
          "risk": "safe"
        }
      ]
    },
    {
      "id": "jarvisos-web",
      "name": "JarvisOS Web PWA",
      "kind": "service",
      "tier": "standard",
      "declared": false,
      "external": false,
      "status": "unknown",
      "affected": 0,
      "criticalAffected": 0,
      "lostWeight": 8,
      "capabilities": [
        {
          "id": "estate-visibility",
          "label": "Knowing what is broken",
          "weight": 8
        }
      ],
      "actions": [
        {
          "id": "restart-jarvisos-web",
          "label": "Restart the JarvisOS console on VIN",
          "etaSec": 60,
          "risk": "safe"
        }
      ]
    },
    {
      "id": "internal-dns",
      "name": "Internal DNS",
      "kind": "dns",
      "tier": "important",
      "declared": true,
      "external": false,
      "status": "unknown",
      "affected": 0,
      "criticalAffected": 0,
      "lostWeight": 6,
      "capabilities": [
        {
          "id": "internal-names",
          "label": "Internal name resolution",
          "weight": 6
        }
      ],
      "actions": [
        {
          "id": "restart-internal-dns",
          "label": "Restart the internal resolver on Home1",
          "etaSec": 120,
          "risk": "safe"
        }
      ]
    }
  ],
  "paths": [
    {
      "id": "published-web",
      "label": "Published web",
      "blurb": "Every hostname this estate answers on, from outside the house.",
      "weight": 22,
      "impact": "Noticed within seconds by anyone using anything. This is what 'the estate is down' means to a human.",
      "entries": [
        "caddy"
      ],
      "chain": [
        {
          "id": "caddy",
          "name": "Caddy (reverse proxy)",
          "kind": "service",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 0,
          "criticalAffected": 0,
          "lostWeight": 22,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            }
          ],
          "actions": [
            {
              "id": "restart-caddy",
              "label": "Restart Caddy on VIN",
              "etaSec": 120,
              "risk": "disruptive"
            }
          ],
          "hops": 0
        },
        {
          "id": "cloudflare-dns",
          "name": "Public DNS",
          "kind": "dns",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 1,
          "criticalAffected": 1,
          "lostWeight": 36,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            }
          ],
          "actions": [
            {
              "id": "repoint-public-dns",
              "label": "Re-point the public DNS records",
              "etaSec": 1800,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        },
        {
          "id": "vin",
          "name": "VIN / VPS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 12,
          "criticalAffected": 5,
          "lostWeight": 86,
          "capabilities": [
            {
              "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
            }
          ],
          "actions": [
            {
              "id": "reboot-vin",
              "label": "Reboot VIN",
              "etaSec": 600,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        },
        {
          "id": "isp-uplink",
          "name": "ISP Uplink",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 11,
          "criticalAffected": 8,
          "lostWeight": 90,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            },
            {
              "id": "private-access",
              "label": "Private access to the estate",
              "weight": 10
            }
          ],
          "actions": [],
          "hops": 2
        }
      ],
      "redundant": []
    },
    {
      "id": "sign-in",
      "label": "Sign-in",
      "blurb": "Issuing and validating sessions for everything behind SSO.",
      "weight": 18,
      "impact": "An auth outage looks like a total outage: the services are up and nobody can reach them.",
      "entries": [
        "jarvisos-auth"
      ],
      "chain": [
        {
          "id": "jarvisos-auth",
          "name": "JarvisOS Auth (SSO)",
          "kind": "auth",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 2,
          "criticalAffected": 1,
          "lostWeight": 34,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            }
          ],
          "actions": [
            {
              "id": "restart-auth",
              "label": "Restart JarvisOS Auth on VIN",
              "etaSec": 180,
              "risk": "disruptive"
            }
          ],
          "hops": 0
        },
        {
          "id": "google-oauth",
          "name": "Google OAuth",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 3,
          "criticalAffected": 2,
          "lostWeight": 34,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            }
          ],
          "actions": [],
          "hops": 1
        },
        {
          "id": "redis",
          "name": "Redis (cache / queue)",
          "kind": "database",
          "tier": "important",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 3,
          "criticalAffected": 2,
          "lostWeight": 34,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            }
          ],
          "actions": [
            {
              "id": "restart-redis",
              "label": "Restart Redis on Home1",
              "etaSec": 120,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        },
        {
          "id": "vin",
          "name": "VIN / VPS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 12,
          "criticalAffected": 5,
          "lostWeight": 86,
          "capabilities": [
            {
              "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
            }
          ],
          "actions": [
            {
              "id": "reboot-vin",
              "label": "Reboot VIN",
              "etaSec": 600,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        },
        {
          "id": "home1",
          "name": "Home1",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 6,
          "criticalAffected": 3,
          "lostWeight": 60,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "data-writes",
              "label": "Data writes",
              "weight": 20
            },
            {
              "id": "internal-names",
              "label": "Internal name resolution",
              "weight": 6
            }
          ],
          "actions": [
            {
              "id": "restore-home1",
              "label": "Restore power and boot Home1",
              "etaSec": 1800,
              "risk": "disruptive"
            }
          ],
          "hops": 2
        },
        {
          "id": "isp-uplink",
          "name": "ISP Uplink",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 11,
          "criticalAffected": 8,
          "lostWeight": 90,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            },
            {
              "id": "private-access",
              "label": "Private access to the estate",
              "weight": 10
            }
          ],
          "actions": [],
          "hops": 2
        }
      ],
      "redundant": []
    },
    {
      "id": "orchestration",
      "label": "JarvisOS orchestration",
      "blurb": "Accepting, scheduling and dispatching work across the fleet.",
      "weight": 16,
      "impact": "Running work continues; nothing new starts. Noticed at the next dispatch rather than immediately.",
      "entries": [
        "jarvisos-control-plane"
      ],
      "chain": [
        {
          "id": "jarvisos-control-plane",
          "name": "JarvisOS Control Plane",
          "kind": "service",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 1,
          "criticalAffected": 0,
          "lostWeight": 16,
          "capabilities": [
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            }
          ],
          "actions": [
            {
              "id": "failover-control-plane-to-vin",
              "label": "Bring up the standby control plane on VIN",
              "etaSec": 900,
              "risk": "disruptive"
            }
          ],
          "hops": 0
        },
        {
          "id": "home1",
          "name": "Home1",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 6,
          "criticalAffected": 3,
          "lostWeight": 60,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "data-writes",
              "label": "Data writes",
              "weight": 20
            },
            {
              "id": "internal-names",
              "label": "Internal name resolution",
              "weight": 6
            }
          ],
          "actions": [
            {
              "id": "restore-home1",
              "label": "Restore power and boot Home1",
              "etaSec": 1800,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        },
        {
          "id": "jarvisos-auth",
          "name": "JarvisOS Auth (SSO)",
          "kind": "auth",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 2,
          "criticalAffected": 1,
          "lostWeight": 34,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            }
          ],
          "actions": [
            {
              "id": "restart-auth",
              "label": "Restart JarvisOS Auth on VIN",
              "etaSec": 180,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        },
        {
          "id": "google-oauth",
          "name": "Google OAuth",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 3,
          "criticalAffected": 2,
          "lostWeight": 34,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            }
          ],
          "actions": [],
          "hops": 2
        },
        {
          "id": "redis",
          "name": "Redis (cache / queue)",
          "kind": "database",
          "tier": "important",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 3,
          "criticalAffected": 2,
          "lostWeight": 34,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            }
          ],
          "actions": [
            {
              "id": "restart-redis",
              "label": "Restart Redis on Home1",
              "etaSec": 120,
              "risk": "disruptive"
            }
          ],
          "hops": 2
        },
        {
          "id": "vin",
          "name": "VIN / VPS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 12,
          "criticalAffected": 5,
          "lostWeight": 86,
          "capabilities": [
            {
              "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
            }
          ],
          "actions": [
            {
              "id": "reboot-vin",
              "label": "Reboot VIN",
              "etaSec": 600,
              "risk": "disruptive"
            }
          ],
          "hops": 2
        },
        {
          "id": "isp-uplink",
          "name": "ISP Uplink",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 11,
          "criticalAffected": 8,
          "lostWeight": 90,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            },
            {
              "id": "private-access",
              "label": "Private access to the estate",
              "weight": 10
            }
          ],
          "actions": [],
          "hops": 3
        }
      ],
      "redundant": []
    },
    {
      "id": "jarvis-ai",
      "label": "JarvisAI agent surface",
      "blurb": "The MCP agent on VIN and the tunnel that publishes it.",
      "weight": 12,
      "impact": "Assistant-driven work stops. Nothing else notices.",
      "entries": [
        "jarvis-mcp"
      ],
      "chain": [
        {
          "id": "jarvis-mcp",
          "name": "JarvisMCP node agent",
          "kind": "service",
          "tier": "standard",
          "declared": false,
          "external": false,
          "status": "unknown",
          "affected": 0,
          "criticalAffected": 0,
          "lostWeight": 12,
          "capabilities": [
            {
              "id": "jarvis-ai",
              "label": "JarvisAI agent surface",
              "weight": 12
            }
          ],
          "actions": [
            {
              "id": "restart-jarvis-mcp",
              "label": "Restart the JarvisMCP agent on VIN",
              "etaSec": 90,
              "risk": "safe"
            }
          ],
          "hops": 0
        },
        {
          "id": "vin",
          "name": "VIN / VPS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 12,
          "criticalAffected": 5,
          "lostWeight": 86,
          "capabilities": [
            {
              "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
            }
          ],
          "actions": [
            {
              "id": "reboot-vin",
              "label": "Reboot VIN",
              "etaSec": 600,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        }
      ],
      "redundant": []
    },
    {
      "id": "data-writes",
      "label": "Data writes",
      "blurb": "The Postgres role that accepts writes.",
      "weight": 20,
      "impact": "Immediate and total for anything stateful. Recoverable only by promotion, which is one-way.",
      "entries": [
        "postgres-primary"
      ],
      "chain": [
        {
          "id": "postgres-primary",
          "name": "Postgres (primary)",
          "kind": "database",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 0,
          "criticalAffected": 0,
          "lostWeight": 20,
          "capabilities": [
            {
              "id": "data-writes",
              "label": "Data writes",
              "weight": 20
            }
          ],
          "actions": [
            {
              "id": "promote-postgres-replica",
              "label": "Promote the Postgres replica on VIN",
              "etaSec": 900,
              "risk": "destructive"
            }
          ],
          "hops": 0
        },
        {
          "id": "home1",
          "name": "Home1",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 6,
          "criticalAffected": 3,
          "lostWeight": 60,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "data-writes",
              "label": "Data writes",
              "weight": 20
            },
            {
              "id": "internal-names",
              "label": "Internal name resolution",
              "weight": 6
            }
          ],
          "actions": [
            {
              "id": "restore-home1",
              "label": "Restore power and boot Home1",
              "etaSec": 1800,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        }
      ],
      "redundant": []
    },
    {
      "id": "data-reads",
      "label": "Data reads",
      "blurb": "Reading the system of record, from either the primary or the streaming replica.",
      "weight": 14,
      "impact": "Survives the loss of the home rack, which is the whole reason the replica exists.",
      "entries": [
        "postgres-primary",
        "postgres-replica"
      ],
      "chain": [],
      "redundant": [
        [
          "postgres-primary",
          "postgres-replica"
        ]
      ]
    },
    {
      "id": "backups",
      "label": "On-site backups",
      "blurb": "The NAS dataset every backup lands in.",
      "weight": 12,
      "impact": "Nothing breaks today; the estate silently stops being recoverable. The worst failure mode here.",
      "entries": [
        "nas-backups"
      ],
      "chain": [
        {
          "id": "nas-backups",
          "name": "NAS backup dataset",
          "kind": "storage",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 1,
          "criticalAffected": 1,
          "lostWeight": 22,
          "capabilities": [
            {
              "id": "backups",
              "label": "On-site backups",
              "weight": 12
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            }
          ],
          "actions": [
            {
              "id": "remount-nas-backups",
              "label": "Bring the backup dataset back online",
              "etaSec": 900,
              "risk": "disruptive"
            }
          ],
          "hops": 0
        },
        {
          "id": "nas",
          "name": "NAS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 3,
          "criticalAffected": 2,
          "lostWeight": 22,
          "capabilities": [
            {
              "id": "backups",
              "label": "On-site backups",
              "weight": 12
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            }
          ],
          "actions": [
            {
              "id": "restore-nas",
              "label": "Bring the NAS back",
              "etaSec": 3600,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        }
      ],
      "redundant": []
    },
    {
      "id": "offsite-recovery",
      "label": "Offsite recovery",
      "blurb": "The offsite copy that survives losing the home rack entirely.",
      "weight": 10,
      "impact": "Invisible until the day the house is the incident.",
      "entries": [
        "gwscli-s3-offsite"
      ],
      "chain": [
        {
          "id": "gwscli-s3-offsite",
          "name": "Offsite backup replica",
          "kind": "replica",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 0,
          "criticalAffected": 0,
          "lostWeight": 10,
          "capabilities": [
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            }
          ],
          "actions": [
            {
              "id": "rerun-offsite-sync",
              "label": "Re-run the offsite sync",
              "etaSec": 2400,
              "risk": "safe"
            }
          ],
          "hops": 0
        },
        {
          "id": "gwscli-s3",
          "name": "GWSCLI / S3",
          "kind": "node",
          "tier": "important",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 1,
          "criticalAffected": 1,
          "lostWeight": 10,
          "capabilities": [
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            }
          ],
          "actions": [],
          "hops": 1
        },
        {
          "id": "isp-uplink",
          "name": "ISP Uplink",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 11,
          "criticalAffected": 8,
          "lostWeight": 90,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            },
            {
              "id": "private-access",
              "label": "Private access to the estate",
              "weight": 10
            }
          ],
          "actions": [],
          "hops": 1
        },
        {
          "id": "nas-backups",
          "name": "NAS backup dataset",
          "kind": "storage",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 1,
          "criticalAffected": 1,
          "lostWeight": 22,
          "capabilities": [
            {
              "id": "backups",
              "label": "On-site backups",
              "weight": 12
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            }
          ],
          "actions": [
            {
              "id": "remount-nas-backups",
              "label": "Bring the backup dataset back online",
              "etaSec": 900,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        },
        {
          "id": "nas",
          "name": "NAS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 3,
          "criticalAffected": 2,
          "lostWeight": 22,
          "capabilities": [
            {
              "id": "backups",
              "label": "On-site backups",
              "weight": 12
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            }
          ],
          "actions": [
            {
              "id": "restore-nas",
              "label": "Bring the NAS back",
              "etaSec": 3600,
              "risk": "disruptive"
            }
          ],
          "hops": 2
        }
      ],
      "redundant": []
    },
    {
      "id": "public-names",
      "label": "Public name resolution",
      "blurb": "Cloudflare DNS: turning published hostnames into an address.",
      "weight": 14,
      "impact": "Looks exactly like a total outage from outside, and clients cache the failure.",
      "entries": [
        "cloudflare-dns"
      ],
      "chain": [
        {
          "id": "cloudflare-dns",
          "name": "Public DNS",
          "kind": "dns",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 1,
          "criticalAffected": 1,
          "lostWeight": 36,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            }
          ],
          "actions": [
            {
              "id": "repoint-public-dns",
              "label": "Re-point the public DNS records",
              "etaSec": 1800,
              "risk": "disruptive"
            }
          ],
          "hops": 0
        },
        {
          "id": "isp-uplink",
          "name": "ISP Uplink",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 11,
          "criticalAffected": 8,
          "lostWeight": 90,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            },
            {
              "id": "private-access",
              "label": "Private access to the estate",
              "weight": 10
            }
          ],
          "actions": [],
          "hops": 1
        }
      ],
      "redundant": []
    },
    {
      "id": "internal-names",
      "label": "Internal name resolution",
      "blurb": "Resolving estate names on the LAN.",
      "weight": 6,
      "impact": "Home1 clients lose names; the secondary resolver on VIN answers automatically.",
      "entries": [
        "internal-dns"
      ],
      "chain": [
        {
          "id": "internal-dns",
          "name": "Internal DNS",
          "kind": "dns",
          "tier": "important",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 0,
          "criticalAffected": 0,
          "lostWeight": 6,
          "capabilities": [
            {
              "id": "internal-names",
              "label": "Internal name resolution",
              "weight": 6
            }
          ],
          "actions": [
            {
              "id": "restart-internal-dns",
              "label": "Restart the internal resolver on Home1",
              "etaSec": 120,
              "risk": "safe"
            }
          ],
          "hops": 0
        },
        {
          "id": "home1",
          "name": "Home1",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 6,
          "criticalAffected": 3,
          "lostWeight": 60,
          "capabilities": [
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "data-writes",
              "label": "Data writes",
              "weight": 20
            },
            {
              "id": "internal-names",
              "label": "Internal name resolution",
              "weight": 6
            }
          ],
          "actions": [
            {
              "id": "restore-home1",
              "label": "Restore power and boot Home1",
              "etaSec": 1800,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        }
      ],
      "redundant": []
    },
    {
      "id": "private-access",
      "label": "Private access to the estate",
      "blurb": "Reaching nodes without going through anything published — the tailnet, or the WireGuard link.",
      "weight": 10,
      "impact": "Losing both is what turns a service incident into 'nobody can get in to fix it'.",
      "entries": [
        "tailscaled",
        "wireguard-tunnel"
      ],
      "chain": [
        {
          "id": "isp-uplink",
          "name": "ISP Uplink",
          "kind": "dependency",
          "tier": "critical",
          "declared": true,
          "external": true,
          "status": "unknown",
          "affected": 11,
          "criticalAffected": 8,
          "lostWeight": 90,
          "capabilities": [
            {
              "id": "published-web",
              "label": "Published web",
              "weight": 22
            },
            {
              "id": "sign-in",
              "label": "Sign-in",
              "weight": 18
            },
            {
              "id": "orchestration",
              "label": "JarvisOS orchestration",
              "weight": 16
            },
            {
              "id": "offsite-recovery",
              "label": "Offsite recovery",
              "weight": 10
            },
            {
              "id": "public-names",
              "label": "Public name resolution",
              "weight": 14
            },
            {
              "id": "private-access",
              "label": "Private access to the estate",
              "weight": 10
            }
          ],
          "actions": [],
          "hops": 1
        },
        {
          "id": "vin",
          "name": "VIN / VPS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 12,
          "criticalAffected": 5,
          "lostWeight": 86,
          "capabilities": [
            {
              "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
            }
          ],
          "actions": [
            {
              "id": "reboot-vin",
              "label": "Reboot VIN",
              "etaSec": 600,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        }
      ],
      "redundant": [
        [
          "tailscaled",
          "wireguard-tunnel"
        ]
      ]
    },
    {
      "id": "estate-visibility",
      "label": "Knowing what is broken",
      "blurb": "This console: status, incidents, recovery tasks and the catalogue.",
      "weight": 8,
      "impact": "Everything still works and nobody can see it. Recovery becomes guesswork.",
      "entries": [
        "jarvisos-web"
      ],
      "chain": [
        {
          "id": "jarvisos-web",
          "name": "JarvisOS Web PWA",
          "kind": "service",
          "tier": "standard",
          "declared": false,
          "external": false,
          "status": "unknown",
          "affected": 0,
          "criticalAffected": 0,
          "lostWeight": 8,
          "capabilities": [
            {
              "id": "estate-visibility",
              "label": "Knowing what is broken",
              "weight": 8
            }
          ],
          "actions": [
            {
              "id": "restart-jarvisos-web",
              "label": "Restart the JarvisOS console on VIN",
              "etaSec": 60,
              "risk": "safe"
            }
          ],
          "hops": 0
        },
        {
          "id": "vin",
          "name": "VIN / VPS",
          "kind": "node",
          "tier": "critical",
          "declared": true,
          "external": false,
          "status": "unknown",
          "affected": 12,
          "criticalAffected": 5,
          "lostWeight": 86,
          "capabilities": [
            {
              "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
            }
          ],
          "actions": [
            {
              "id": "reboot-vin",
              "label": "Reboot VIN",
              "etaSec": 600,
              "risk": "disruptive"
            }
          ],
          "hops": 1
        }
      ],
      "redundant": []
    }
  ],
  "ranking": {
    "at": "2026-08-18T06:53:53.704Z",
    "roots": [],
    "down": [],
    "lost": [],
    "lostWeight": 0,
    "availableWeight": 162,
    "totalWeight": 162,
    "actions": [],
    "best": null
  },
  "focus": null,
  "nodes": [
    {
      "id": "jarvisos-auth",
      "name": "JarvisOS Auth (SSO)",
      "kind": "auth",
      "tier": "critical",
      "node": "vin",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-jarvisos-auth",
      "capabilities": [
        "sign-in",
        "orchestration"
      ],
      "dependsOn": [
        "vin",
        "google-oauth",
        "redis"
      ],
      "dependents": [
        "jarvisos-control-plane"
      ],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "google-oauth"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "redis"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "postgres-primary",
      "name": "Postgres (primary)",
      "kind": "database",
      "tier": "critical",
      "node": "home1",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-postgres-primary",
      "capabilities": [
        "orchestration",
        "data-writes",
        "data-reads"
      ],
      "dependsOn": [
        "home1"
      ],
      "dependents": [
        "jarvisos-control-plane"
      ],
      "requires": [
        {
          "members": [
            "home1"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "redis",
      "name": "Redis (cache / queue)",
      "kind": "database",
      "tier": "important",
      "node": "home1",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-redis",
      "capabilities": [
        "sign-in",
        "orchestration"
      ],
      "dependsOn": [
        "home1"
      ],
      "dependents": [
        "jarvisos-auth"
      ],
      "requires": [
        {
          "members": [
            "home1"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "google-oauth",
      "name": "Google OAuth",
      "kind": "dependency",
      "tier": "critical",
      "node": null,
      "external": true,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-google-oauth",
      "capabilities": [
        "sign-in",
        "orchestration"
      ],
      "dependsOn": [
        "isp-uplink"
      ],
      "dependents": [
        "jarvisos-auth"
      ],
      "requires": [
        {
          "members": [
            "isp-uplink"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "isp-uplink",
      "name": "ISP Uplink",
      "kind": "dependency",
      "tier": "critical",
      "node": null,
      "external": true,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-isp-uplink",
      "capabilities": [
        "published-web",
        "sign-in",
        "orchestration",
        "jarvis-ai",
        "data-reads",
        "offsite-recovery",
        "public-names",
        "private-access",
        "estate-visibility"
      ],
      "dependsOn": [],
      "dependents": [
        "google-oauth",
        "wireguard-tunnel",
        "cloudflare-dns",
        "gwscli-s3-offsite",
        "tailscaled",
        "jarvis-tunnel"
      ],
      "requires": []
    },
    {
      "id": "internal-dns",
      "name": "Internal DNS",
      "kind": "dns",
      "tier": "important",
      "node": "home1",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-internal-dns",
      "capabilities": [
        "internal-names"
      ],
      "dependsOn": [
        "home1"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "home1"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "cloudflare-dns",
      "name": "Public DNS",
      "kind": "dns",
      "tier": "critical",
      "node": null,
      "external": true,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-cloudflare-dns",
      "capabilities": [
        "published-web",
        "public-names"
      ],
      "dependsOn": [
        "isp-uplink"
      ],
      "dependents": [
        "caddy"
      ],
      "requires": [
        {
          "members": [
            "isp-uplink"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "gwscli-s3",
      "name": "GWSCLI / S3",
      "kind": "node",
      "tier": "important",
      "node": "gwscli-s3",
      "external": true,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-gwscli-s3",
      "capabilities": [
        "offsite-recovery"
      ],
      "dependsOn": [],
      "dependents": [
        "gwscli-s3-offsite"
      ],
      "requires": []
    },
    {
      "id": "home1",
      "name": "Home1",
      "kind": "node",
      "tier": "critical",
      "node": "home1",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-home1",
      "capabilities": [
        "sign-in",
        "orchestration",
        "data-writes",
        "data-reads",
        "internal-names"
      ],
      "dependsOn": [],
      "dependents": [
        "jarvisos-control-plane",
        "postgres-primary",
        "redis",
        "internal-dns"
      ],
      "requires": []
    },
    {
      "id": "nas",
      "name": "NAS",
      "kind": "node",
      "tier": "critical",
      "node": "nas",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-nas",
      "capabilities": [
        "backups",
        "offsite-recovery"
      ],
      "dependsOn": [],
      "dependents": [
        "nas-backups",
        "nas-media"
      ],
      "requires": []
    },
    {
      "id": "vin",
      "name": "VIN / VPS",
      "kind": "node",
      "tier": "critical",
      "node": "vin",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-vin",
      "capabilities": [
        "published-web",
        "sign-in",
        "orchestration",
        "jarvis-ai",
        "data-reads",
        "private-access",
        "estate-visibility"
      ],
      "dependsOn": [],
      "dependents": [
        "jarvisos-worker",
        "caddy",
        "postgres-replica",
        "jarvisos-auth",
        "wireguard-tunnel",
        "dockerd",
        "jarvis-mcp",
        "jarvisos-web-proxy",
        "jarvisos-web",
        "tailscaled",
        "jarvis-tunnel"
      ],
      "requires": []
    },
    {
      "id": "vps1",
      "name": "VPS1 / de-james-vps1",
      "kind": "node",
      "tier": "important",
      "node": "vps1",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "unknown",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "/independence",
      "capabilities": [],
      "dependsOn": [],
      "dependents": [],
      "requires": []
    },
    {
      "id": "gwscli-s3-offsite",
      "name": "Offsite backup replica",
      "kind": "replica",
      "tier": "critical",
      "node": "gwscli-s3",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-gwscli-s3-offsite",
      "capabilities": [
        "offsite-recovery"
      ],
      "dependsOn": [
        "gwscli-s3",
        "nas-backups",
        "isp-uplink"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "gwscli-s3"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "nas-backups"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "isp-uplink"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "postgres-replica",
      "name": "Postgres (replica)",
      "kind": "replica",
      "tier": "critical",
      "node": "vin",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-postgres-replica",
      "capabilities": [
        "orchestration",
        "data-reads"
      ],
      "dependsOn": [
        "vin",
        "wireguard-tunnel"
      ],
      "dependents": [
        "jarvisos-control-plane"
      ],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "wireguard-tunnel"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "caddy",
      "name": "Caddy (reverse proxy)",
      "kind": "service",
      "tier": "critical",
      "node": "vin",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-caddy",
      "capabilities": [
        "published-web"
      ],
      "dependsOn": [
        "vin",
        "cloudflare-dns"
      ],
      "dependents": [
        "jarvisos-web"
      ],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "cloudflare-dns"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "dockerd",
      "name": "Docker engine (VIN)",
      "kind": "service",
      "tier": "standard",
      "node": "vin",
      "external": false,
      "declared": false,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": null,
      "capabilities": [],
      "dependsOn": [
        "vin"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "jarvis-mcp",
      "name": "JarvisMCP node agent",
      "kind": "service",
      "tier": "standard",
      "node": "vin",
      "external": false,
      "declared": false,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": null,
      "capabilities": [
        "jarvis-ai"
      ],
      "dependsOn": [
        "vin"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "jarvisos-control-plane",
      "name": "JarvisOS Control Plane",
      "kind": "service",
      "tier": "critical",
      "node": "home1",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-jarvisos-control-plane",
      "capabilities": [
        "orchestration"
      ],
      "dependsOn": [
        "home1",
        "postgres-primary",
        "jarvisos-auth",
        "postgres-replica"
      ],
      "dependents": [
        "jarvisos-worker"
      ],
      "requires": [
        {
          "members": [
            "postgres-primary",
            "postgres-replica"
          ],
          "kind": "redundant",
          "manual": true,
          "via": "promote-postgres-replica",
          "stale": false
        },
        {
          "members": [
            "home1"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "jarvisos-auth"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "jarvisos-web-proxy",
      "name": "JarvisOS Web Docker bridge proxy",
      "kind": "service",
      "tier": "standard",
      "node": "vin",
      "external": false,
      "declared": false,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": null,
      "capabilities": [],
      "dependsOn": [
        "vin"
      ],
      "dependents": [
        "jarvisos-web"
      ],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "jarvisos-web",
      "name": "JarvisOS Web PWA",
      "kind": "service",
      "tier": "standard",
      "node": "vin",
      "external": false,
      "declared": false,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": null,
      "capabilities": [
        "estate-visibility"
      ],
      "dependsOn": [
        "vin",
        "caddy",
        "jarvisos-web-proxy"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "jarvisos-worker",
      "name": "JarvisOS Worker (VIN)",
      "kind": "service",
      "tier": "important",
      "node": "vin",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-jarvisos-worker",
      "capabilities": [
        "orchestration"
      ],
      "dependsOn": [
        "vin",
        "jarvisos-control-plane",
        "wireguard-tunnel"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "jarvisos-control-plane"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "wireguard-tunnel"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "tailscaled",
      "name": "Tailscale daemon (VIN)",
      "kind": "service",
      "tier": "standard",
      "node": "vin",
      "external": false,
      "declared": false,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": null,
      "capabilities": [
        "private-access",
        "estate-visibility"
      ],
      "dependsOn": [
        "vin",
        "isp-uplink"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "isp-uplink"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "nas-backups",
      "name": "NAS backup dataset",
      "kind": "storage",
      "tier": "critical",
      "node": "nas",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-nas-backups",
      "capabilities": [
        "backups",
        "offsite-recovery"
      ],
      "dependsOn": [
        "nas"
      ],
      "dependents": [
        "gwscli-s3-offsite"
      ],
      "requires": [
        {
          "members": [
            "nas"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "nas-media",
      "name": "NAS media dataset",
      "kind": "storage",
      "tier": "standard",
      "node": "nas",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-nas-media",
      "capabilities": [],
      "dependsOn": [
        "nas"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "nas"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "jarvis-tunnel",
      "name": "Secure MCP tunnel",
      "kind": "tunnel",
      "tier": "standard",
      "node": "vin",
      "external": false,
      "declared": false,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": null,
      "capabilities": [
        "jarvis-ai"
      ],
      "dependsOn": [
        "vin",
        "isp-uplink"
      ],
      "dependents": [],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "isp-uplink"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    },
    {
      "id": "wireguard-tunnel",
      "name": "WireGuard (Home1 <-> VIN)",
      "kind": "tunnel",
      "tier": "critical",
      "node": "vin",
      "external": false,
      "declared": true,
      "catalogued": true,
      "status": "unknown",
      "rootCause": false,
      "state": "declared-only",
      "freshness": "missing",
      "lastSeenAt": null,
      "runbook": "docs/RECOVERY.md#rb-wireguard-tunnel",
      "capabilities": [
        "orchestration",
        "data-reads",
        "private-access"
      ],
      "dependsOn": [
        "vin",
        "isp-uplink"
      ],
      "dependents": [
        "postgres-replica",
        "jarvisos-worker"
      ],
      "requires": [
        {
          "members": [
            "vin"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        },
        {
          "members": [
            "isp-uplink"
          ],
          "kind": "single",
          "manual": false,
          "via": null,
          "stale": false
        }
      ]
    }
  ],
  "edges": [
    {
      "from": "jarvisos-control-plane",
      "to": "home1",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-control-plane",
      "to": "postgres-primary",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": "control-plane-database",
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-control-plane",
      "to": "jarvisos-auth",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "curated"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "Sessions issued by jarvisos-auth."
        }
      ]
    },
    {
      "from": "jarvisos-worker",
      "to": "vin",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-worker",
      "to": "jarvisos-control-plane",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "caddy",
      "to": "vin",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "caddy",
      "to": "cloudflare-dns",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "postgres-primary",
      "to": "home1",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "postgres-replica",
      "to": "vin",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "postgres-replica",
      "to": "wireguard-tunnel",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "redis",
      "to": "home1",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-auth",
      "to": "vin",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-auth",
      "to": "google-oauth",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "curated"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "Sessions issued by google-oauth."
        }
      ]
    },
    {
      "from": "jarvisos-auth",
      "to": "redis",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "google-oauth",
      "to": "isp-uplink",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "wireguard-tunnel",
      "to": "vin",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "wireguard-tunnel",
      "to": "isp-uplink",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "cloudflare-dns",
      "to": "isp-uplink",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "internal-dns",
      "to": "home1",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "nas-backups",
      "to": "nas",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "nas-media",
      "to": "nas",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "gwscli-s3-offsite",
      "to": "gwscli-s3",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared",
        "placement"
      ],
      "reason": null,
      "stale": false,
      "corroborated": true,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "gwscli-s3-offsite",
      "to": "nas-backups",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "gwscli-s3-offsite",
      "to": "isp-uplink",
      "mode": "hard",
      "origin": "declared",
      "origins": [
        "declared"
      ],
      "reason": null,
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "inventory",
          "sourceTitle": "config/inventory.json",
          "observedAt": null,
          "freshness": "fresh",
          "detail": "A file this process read at boot."
        },
        {
          "source": "inventory",
          "sourceTitle": "Declared inventory",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "dockerd",
      "to": "vin",
      "mode": "hard",
      "origin": "curated",
      "origins": [
        "curated"
      ],
      "reason": "Runs on this host.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvis-mcp",
      "to": "vin",
      "mode": "hard",
      "origin": "curated",
      "origins": [
        "curated"
      ],
      "reason": "Runs on this host.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-web-proxy",
      "to": "vin",
      "mode": "hard",
      "origin": "curated",
      "origins": [
        "curated"
      ],
      "reason": "Runs on this host.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-web",
      "to": "vin",
      "mode": "hard",
      "origin": "curated",
      "origins": [
        "curated"
      ],
      "reason": "Runs on this host.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "tailscaled",
      "to": "vin",
      "mode": "hard",
      "origin": "curated",
      "origins": [
        "curated"
      ],
      "reason": "Runs on this host.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvis-tunnel",
      "to": "vin",
      "mode": "hard",
      "origin": "curated",
      "origins": [
        "curated"
      ],
      "reason": "Runs on this host.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "catalogue",
          "sourceTitle": "Curated catalogue",
          "observedAt": null,
          "freshness": "fresh",
          "detail": null
        }
      ]
    },
    {
      "from": "jarvisos-worker",
      "to": "wireguard-tunnel",
      "mode": "hard",
      "origin": "override",
      "origins": [
        "override"
      ],
      "reason": "The worker on VIN reaches the control plane on Home1 across the tunnel. Nothing observes this: from Docker's point of view the worker is simply running.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "override",
          "sourceTitle": "config/dependency-graph.json",
          "observedAt": "2026-08-16",
          "freshness": "fresh",
          "detail": "Reviewed by homelab-operator."
        }
      ]
    },
    {
      "from": "tailscaled",
      "to": "isp-uplink",
      "mode": "hard",
      "origin": "override",
      "origins": [
        "override"
      ],
      "reason": "The tailnet needs the uplink to reach the coordination server. A daemon that is running and cannot coordinate is not private access.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "override",
          "sourceTitle": "config/dependency-graph.json",
          "observedAt": "2026-08-16",
          "freshness": "fresh",
          "detail": "Reviewed by homelab-operator."
        }
      ]
    },
    {
      "from": "jarvis-tunnel",
      "to": "isp-uplink",
      "mode": "hard",
      "origin": "override",
      "origins": [
        "override"
      ],
      "reason": "Outbound tunnel: no uplink, no published MCP surface.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "override",
          "sourceTitle": "config/dependency-graph.json",
          "observedAt": "2026-08-16",
          "freshness": "fresh",
          "detail": "Reviewed by homelab-operator."
        }
      ]
    },
    {
      "from": "jarvisos-web",
      "to": "caddy",
      "mode": "soft",
      "origin": "override",
      "origins": [
        "override"
      ],
      "reason": "The console binds loopback and is published through the reverse proxy. Losing Caddy does not stop it — an operator on VIN still has it — so this degrades the console rather than removing it.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "override",
          "sourceTitle": "config/dependency-graph.json",
          "observedAt": "2026-08-16",
          "freshness": "fresh",
          "detail": "Reviewed by homelab-operator."
        }
      ]
    },
    {
      "from": "jarvisos-web",
      "to": "jarvisos-web-proxy",
      "mode": "soft",
      "origin": "override",
      "origins": [
        "override"
      ],
      "reason": "The bridge proxy is how the PWA reaches services on the Docker network. Without it the console renders, with parts of the estate unreachable from it.",
      "stale": false,
      "corroborated": false,
      "group": null,
      "evidence": [
        {
          "source": "override",
          "sourceTitle": "config/dependency-graph.json",
          "observedAt": "2026-08-16",
          "freshness": "fresh",
          "detail": "Reviewed by homelab-operator."
        }
      ]
    }
  ],
  "findings": [
    {
      "severity": "warn",
      "code": "graph-undeclared-on-path",
      "title": "JarvisMCP node agent holds up 1 capability/capabilities and is not in the inventory",
      "detail": "It is in the catalogue only, so it has no tier, no availability class and no runbook. Anything a declared capability depends on should be declared.",
      "nodeId": "jarvis-mcp"
    },
    {
      "severity": "warn",
      "code": "graph-undeclared-on-path",
      "title": "JarvisOS Web PWA holds up 1 capability/capabilities and is not in the inventory",
      "detail": "It is in the catalogue only, so it has no tier, no availability class and no runbook. Anything a declared capability depends on should be declared.",
      "nodeId": "jarvisos-web"
    },
    {
      "severity": "warn",
      "code": "graph-undeclared-on-path",
      "title": "Tailscale daemon (VIN) holds up 2 capability/capabilities and is not in the inventory",
      "detail": "It is in the catalogue only, so it has no tier, no availability class and no runbook. Anything a declared capability depends on should be declared.",
      "nodeId": "tailscaled"
    },
    {
      "severity": "warn",
      "code": "graph-undeclared-on-path",
      "title": "Secure MCP tunnel holds up 1 capability/capabilities and is not in the inventory",
      "detail": "It is in the catalogue only, so it has no tier, no availability class and no runbook. Anything a declared capability depends on should be declared.",
      "nodeId": "jarvis-tunnel"
    },
    {
      "severity": "info",
      "code": "graph-spof-vendor",
      "title": "ISP Uplink is a single point of failure outside operator control",
      "detail": "Losing it costs 90 capability point(s) (Published web, Sign-in, JarvisOS orchestration, Offsite recovery, Public name resolution, Private access to the estate). There is no action to declare: the recovery path is the vendor's, and the only lever here is the workaround in the runbook.",
      "nodeId": "isp-uplink"
    },
    {
      "severity": "info",
      "code": "graph-spof-vendor",
      "title": "Google OAuth is a single point of failure outside operator control",
      "detail": "Losing it costs 34 capability point(s) (Sign-in, JarvisOS orchestration). There is no action to declare: the recovery path is the vendor's, and the only lever here is the workaround in the runbook.",
      "nodeId": "google-oauth"
    },
    {
      "severity": "info",
      "code": "graph-spof-vendor",
      "title": "GWSCLI / S3 is a single point of failure outside operator control",
      "detail": "Losing it costs 10 capability point(s) (Offsite recovery). There is no action to declare: the recovery path is the vendor's, and the only lever here is the workaround in the runbook.",
      "nodeId": "gwscli-s3"
    }
  ],
  "source": "/app/config/dependency-graph.json"
}