{
  "schema": 2,
  "domain": "tcp.systems",
  "generation_id": "20261110T124844Z-b40072d0",
  "generated": "2026-11-10T12:48:44.160Z",
  "generated_epoch": 1794314924,
  "budget_s": 600,
  "mode": "snapshot",
  "honesty": "Static snapshot. Every verdict was measured at `generated`; freshness is the reader's computation, and a stale snapshot is reported stale rather than refreshed silently.",
  "publication": "This set is staged complete (page, status.json, incidents.json, manifest.json share `generation_id`) and installed by one atomic switch; a failed run leaves the previous generation served and its `generated` unchanged.",
  "realtime": {
    "mode": "push",
    "endpoint": "/api/events",
    "reason": "SSE /api/events (server/status-events.mjs behind Caddy on the status host) pushes a `snapshot` event with the artifact's generated timestamp and rollup when the generator installs a new snapshot; the page reloads onto it. The rows remain a snapshot measured at `generated`, not a live prober."
  },
  "rollup": {
    "total": 15,
    "up": 13,
    "stub": 0,
    "down": 2,
    "unprobed": 0,
    "state": "degraded"
  },
  "entries": [
    {
      "id": "ai",
      "name": "Acumen gateway",
      "host": "ai.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/acumen",
      "impl": "acumen-vnext@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/readyz",
        "expect": 200,
        "contract": "GET /readyz -> 200 only when the acumen gateway answers a body on the public edge; used instead of a static placeholder path."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.197Z",
      "status": "up",
      "http": 200,
      "ms": 54,
      "body_bytes": 34
    },
    {
      "id": "apex",
      "name": "Apex (tcp.systems)",
      "host": "tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/ops",
      "impl": "apex-caddy@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/",
        "expect": 200,
        "contract": "GET / -> 200 from the apex site; a Caddy placeholder/empty 200 is classified down by the empty-body rule."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.252Z",
      "status": "up",
      "http": 200,
      "ms": 38,
      "body_bytes": 73850
    },
    {
      "id": "console",
      "name": "Console",
      "host": "console.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/console",
      "impl": "console-login-only@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/api/health",
        "expect": 200,
        "contract": "GET /api/health -> 200 JSON {status:'ok',service:'console',ts} (~/src/tcpsystems/console/src/routes/api/health/+server.ts). A placeholder body containing `service not yet wired` is classified stub; empty 200 is classified down."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.290Z",
      "status": "up",
      "http": 200,
      "ms": 36,
      "body_bytes": 54
    },
    {
      "id": "auth",
      "name": "Auth (Pocket ID)",
      "host": "auth.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/auth",
      "impl": "authd@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/.well-known/openid-configuration",
        "expect": 200,
        "contract": "GET /.well-known/openid-configuration -> 200 with an OIDC discovery document; this avoids probing login UI copy."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.326Z",
      "status": "up",
      "http": 200,
      "ms": 42,
      "body_bytes": 1843
    },
    {
      "id": "status",
      "name": "Status",
      "host": "status.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/status",
      "impl": "status@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/api/status.json",
        "expect": 200,
        "contract": "GET /api/status.json -> 200 with a parseable JSON body (probe.json: true, so an error page or truncated file is DOWN, not UP). Rows are written by the generator and the check runs from the generator's host, which sees the public edge rather than the origin: an edge or Caddy misconfiguration shows here, a status job that is up but serving stale bytes does not — that is what the reader-computed stale badge reports.",
        "json": true
      },
      "observer": {
        "kind": "external-http",
        "endpoint": "https://status.tcp.systems/api/status.json",
        "expect": 200,
        "contract": "Independent observer contract (not executed by this generator): an off-host/external checker may GET /api/status.json and require HTTP 200 with parseable JSON carrying generated, rollup and entries. This does not make the generator self-probe live."
      },
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.368Z",
      "status": "up",
      "http": 200,
      "ms": 14,
      "body_bytes": 13185
    },
    {
      "id": "chat",
      "name": "Chat",
      "host": "chat.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/chat",
      "impl": "nomad:chat@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/healthz",
        "expect": 200,
        "contract": "GET /healthz -> 200 from chatd behind the scaleblade edge."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.383Z",
      "status": "up",
      "http": 200,
      "ms": 25,
      "body_bytes": 125
    },
    {
      "id": "iptv",
      "name": "IPTV",
      "host": "iptv.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/iptv",
      "impl": "nomad:iptv@eg1",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/",
        "expect": 200,
        "contract": "GET / -> 200 with the non-empty catalog page. /healthz, /readyz and /metrics are deliberately 404 at the public edge (Caddy @internal), so they cannot be probed."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.408Z",
      "status": "down",
      "http": 502,
      "ms": 155,
      "body_bytes": 0,
      "note": "expected 200, got 502"
    },
    {
      "id": "studio",
      "name": "Studio",
      "host": "studio.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/studio",
      "impl": "studiod@dsh",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/",
        "expect": 302,
        "contract": "GET / -> 302 redirect to Pocket ID/OIDC auth when healthy (~/src/tcpsystems/studio/internal/web/web.go; OIDC session gate). HTTP 200 on / means the auth gate is off and is classified down."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.563Z",
      "status": "down",
      "http": 200,
      "ms": 29,
      "body_bytes": 241,
      "note": "expected 302, got 200"
    },
    {
      "id": "search",
      "name": "Search suite",
      "host": "search.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/search",
      "impl": "nomad:search@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/healthz",
        "expect": 200,
        "contract": "GET /healthz -> 200 from the search API behind the scaleblade edge."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.593Z",
      "status": "up",
      "http": 200,
      "ms": 278,
      "body_bytes": 16
    },
    {
      "id": "docs",
      "name": "Docs",
      "host": "docs.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/docs",
      "impl": "nomad:docs@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/",
        "expect": 200,
        "contract": "GET / -> 200 from the docs site behind the scaleblade edge."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.871Z",
      "status": "up",
      "http": 200,
      "ms": 26,
      "body_bytes": 65339
    },
    {
      "id": "mcp",
      "name": "MCP",
      "host": "mcp.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/cli",
      "impl": "nomad:tcp-mcp@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/healthz",
        "expect": 200,
        "contract": "GET /healthz -> 200 from tcp-mcp when the edge service is up (~/src/tcpsystems/cli deploy/runbooks reference /healthz). TLS/certificate availability and JSON-RPC readiness are external follow-ups; empty 200/placeholder is not treated as healthy."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.897Z",
      "status": "up",
      "http": 200,
      "ms": 26,
      "body_bytes": 56
    },
    {
      "id": "dns",
      "name": "DNS page",
      "host": "dns.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/dns",
      "impl": "tcp-dns-page@static",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/",
        "expect": 200,
        "contract": "GET / -> 200 with a non-empty static DNS page body."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.923Z",
      "status": "up",
      "http": 200,
      "ms": 25,
      "body_bytes": 4630
    },
    {
      "id": "radar",
      "name": "Radar intel",
      "host": "radar.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/radar",
      "impl": "nomad:radar@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/healthz",
        "expect": 200,
        "contract": "GET /healthz -> 200 from the radar desk behind the scaleblade edge; its body reports catalog freshness."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.948Z",
      "status": "up",
      "http": 200,
      "ms": 23,
      "body_bytes": 1699
    },
    {
      "id": "massprox",
      "name": "Massprox",
      "host": "massprox.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/massprox",
      "impl": "nomad:massprox@eg1",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/healthz",
        "expect": 200,
        "contract": "GET /healthz -> 200 {\"status\":\"ok\"} from the massprox job (Nomad, eg1) behind the scaleblade edge."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:43.971Z",
      "status": "up",
      "http": 200,
      "ms": 151,
      "body_bytes": 16
    },
    {
      "id": "ui",
      "name": "UI library",
      "host": "ui.tcp.systems",
      "a": "194.180.36.11",
      "owner": "tcpsystems/ui",
      "impl": "caddy-static@scaleblade",
      "class": "product",
      "probe": {
        "kind": "http",
        "path": "/",
        "expect": 200,
        "contract": "GET / -> 200 with the prerendered library site body."
      },
      "observer": null,
      "method": "https",
      "checked_at": "2026-11-10T12:48:44.122Z",
      "status": "up",
      "http": 200,
      "ms": 38,
      "body_bytes": 54017
    }
  ],
  "verdicts": [
    {
      "id": "C1",
      "criterion": "capability",
      "verdict": "pass",
      "evidence": "15/15 surfaces measured at this snapshot; 0 declared and unprobed (no-probe contract)"
    },
    {
      "id": "C2",
      "criterion": "entry-point",
      "verdict": "pass",
      "evidence": "dist/api/status.json (+ /api/incidents.json) is emitted by the same run as the page, so the machine surface cannot drift from the rendered one"
    },
    {
      "id": "C4",
      "criterion": "realtime",
      "verdict": "pass",
      "evidence": "push source declared: SSE /api/events (server/status-events.mjs behind Caddy on the status host) pushes a `snapshot` event with the artifact's generated timestamp and rollup when the generator installs a new snapshot; the page reloads onto it. The rows remain a snapshot measured at `generated`, not a live prober."
    },
    {
      "id": "C6",
      "criterion": "dry-seam",
      "verdict": "pass",
      "evidence": "one declaration (surfaces.json) -> one generator (gen/status-gen.mjs) -> one artifact set; the page reads the JSON, it does not probe"
    },
    {
      "id": "C3",
      "criterion": "incident-feed",
      "verdict": "pass",
      "evidence": "state/incidents.json is operator-curated and copied verbatim (the generator never rewrites it); 1 entr(y|ies) recorded"
    }
  ],
  "stamp": {
    "state": "fresh",
    "age_s": 0,
    "limit_s": 600,
    "basis": "at generation time",
    "caveat": "the scheduler is keeping up; the page badge recomputes the age from the timestamp above, and shows stale past 600s"
  }
}
