{
  "schemaVersion": 2,
  "kind": "surfaces-state",
  "generatedAt": "2026-08-06T07:02:14.219Z",
  "source": "config/surfaces.toml (dig+curl verified 2026-08-04)",
  "surfaces": [
    {
      "id": "apex",
      "host": "factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "@",
      "backend": "cloudflare-pages:project-r-score",
      "backendCode": "cloudflare-pages",
      "pagesProject": "project-r-score",
      "status": "live",
      "protocol": "https-static+functions",
      "access": "public",
      "note": "Apex of the Pages app.",
      "dnsTarget": "project-r-score.pages.dev"
    },
    {
      "id": "www",
      "host": "www.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "www",
      "backend": "cloudflare-pages:project-r-score",
      "backendCode": "cloudflare-pages",
      "pagesProject": "project-r-score",
      "status": "live",
      "protocol": "https-static+functions",
      "access": "public",
      "note": "Same as apex.",
      "dnsTarget": "project-r-score.pages.dev"
    },
    {
      "id": "score",
      "host": "score.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "score",
      "backend": "cloudflare-pages:project-r-score",
      "backendCode": "cloudflare-pages",
      "pagesProject": "project-r-score",
      "status": "live",
      "protocol": "https-static+functions",
      "access": "public",
      "note": "Portal + registry proofs. /portal Access applied 2026-07-28 (302 Access).",
      "dnsTarget": "project-r-score.pages.dev",
      "accessSubpaths": [
        {
          "path": "/portal",
          "access": "applied"
        }
      ]
    },
    {
      "id": "pages_dev",
      "host": "project-r-score.pages.dev",
      "apex": "pages.dev",
      "subdomain": "project-r-score",
      "backend": "cloudflare-pages:project-r-score",
      "backendCode": "cloudflare-pages",
      "pagesProject": "project-r-score",
      "status": "live",
      "protocol": "https-static+functions",
      "access": "public",
      "note": "Pages hostname. /portal Access app applied 2026-07-28 (FactoryWager Portal pages.dev).",
      "dnsTarget": "",
      "accessSubpaths": [
        {
          "path": "/portal",
          "access": "applied"
        }
      ]
    },
    {
      "id": "registry",
      "host": "registry.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "registry",
      "backend": "cloudflare-pages:project-r-score /api/registry/* → R2 factory-wager-registry",
      "backendCode": "cloudflare-pages",
      "pagesProject": "project-r-score",
      "status": "live",
      "protocol": "https-get-only allowlist gateway (npm packuments + proof JSON)",
      "access": "allowlist",
      "note": "Token in bunfig scope is sent but not verified; authz = key allowlist. Writes → 405. Bucket audit 2026-07-28: 12 objects, catalog index (registry.json, 17 pkgs metadata+readme) + ops stub + telegram channels/ — NO storage/ artifacts; installable packuments+tarballs are served from the committed static mirror (public/registry/@factorywager/*), not R2.",
      "dnsTarget": "project-r-score.pages.dev"
    },
    {
      "id": "tennis",
      "host": "tennis.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "tennis",
      "backend": "cloudflare-worker:tennis-hq",
      "backendCode": "cloudflare-worker",
      "status": "live",
      "protocol": "https-static+functions",
      "access": "public",
      "note": "Operator-owned Tennis HQ Worker Custom Domain. Source repo plum-spruce-dawn-dune1 (canonical); Cloudflare manages DNS/TLS. Production tip SHA 8f21bf2 / deploymentId a930f52c (tennis-hq@1.4.0) verified 2026-08-06 via /api/version + R2-first partner ledger/executions (meta.cache=url) + favicon.ico 200 + unauth all five GET /api/v1/* 401 + desk /_serverFn with x-tsr-serverFn. Public shell and identity; partner snapshots R2-first (no D1); all five v1 domains wired and bearer fail-closed when PARTNER_API_TOKEN set. Matches origin/main after Wrangler redeploy.",
      "dnsTarget": ""
    },
    {
      "id": "wiki",
      "host": "wiki.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "wiki",
      "backend": "github-pages",
      "backendCode": "github-pages",
      "status": "live",
      "protocol": "https-static (Jekyll)",
      "access": "public",
      "note": "Docs hub. Proxied via Cloudflare. Do NOT repoint to CF Pages without content migration.",
      "dnsTarget": "brendadeeznuts1111.github.io"
    },
    {
      "id": "ledger",
      "host": "ledger.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "ledger",
      "backend": "cloudflared tunnel accounting-ledger → 127.0.0.1:3000 (this Mac)",
      "backendCode": "cloudflared",
      "status": "live",
      "protocol": "https via cloudflared",
      "access": "applied",
      "note": "Access app APPLIED 2026-07-28 (302 → factory-wager.cloudflareaccess.com login). Tunnel is manual-run only — no launchd.",
      "dnsTarget": "2029fc06-5bbf-415e-9fa1-6b7d3f0b1527.cfargotunnel.com"
    },
    {
      "id": "health_host",
      "host": "health.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "health",
      "backend": "cloudflare-pages:project-r-score (vanity CNAME)",
      "backendCode": "cloudflare-pages",
      "pagesProject": "project-r-score",
      "status": "vanity",
      "protocol": "https-static",
      "access": "public",
      "note": "Serves app landing, NOT health. Real endpoint: score.factory-wager.com/health.",
      "dnsTarget": "project-r-score.pages.dev"
    },
    {
      "id": "telegram_host",
      "host": "telegram.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "telegram",
      "backend": "cloudflare-pages:project-r-score (vanity CNAME)",
      "backendCode": "cloudflare-pages",
      "pagesProject": "project-r-score",
      "status": "vanity",
      "protocol": "https-static",
      "access": "public",
      "note": "Serves app landing, NOT the webhook. Real endpoint: score…/api/telegram/webhook/{tenant}.",
      "dnsTarget": "project-r-score.pages.dev"
    },
    {
      "id": "terminal",
      "host": "terminal.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "terminal",
      "backend": "none — CNAME deleted 2026-07-28 (was → 293ba37a.cfargotunnel.com, orphaned tunnel)",
      "backendCode": "none",
      "status": "retired",
      "protocol": "—",
      "access": "none",
      "note": "CNAME removed via CF API 2026-07-28 (was 502 dangling to the orphan tunnel). Remaining human decisions: delete the dead tunnel in the dashboard + the 293ba37a credential file on this Mac.",
      "dnsTarget": ""
    },
    {
      "id": "support",
      "host": "support.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "support",
      "backend": "none — CNAME deleted 2026-07-28 (was → helpscout.com, no custom-domain cert)",
      "backendCode": "none",
      "status": "retired",
      "protocol": "—",
      "access": "none",
      "note": "CNAME removed via CF API 2026-07-28 (was 525 SSL failure). Re-add only if HelpScout custom-domain SSL is configured first.",
      "dnsTarget": ""
    },
    {
      "id": "reasonix",
      "host": "reasonix.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "reasonix",
      "backend": "none — decommissioned 2026-07-28 (template + staged Access app removed)",
      "backendCode": "none",
      "status": "retired",
      "protocol": "—",
      "access": "none",
      "note": "Never provisioned (no DNS, no tunnel — creation needs the other CF account). Template scripts/cloudflared-reasonix.yml deleted; Access app dropped from .cloudflare-access.yml. Re-create from scratch if ever needed.",
      "dnsTarget": ""
    },
    {
      "id": "registry_write",
      "host": "registry-write.internal.factory-wager.com",
      "apex": "factory-wager.com",
      "subdomain": "registry-write.internal",
      "backend": "none — never provisioned",
      "backendCode": "none",
      "status": "retired",
      "protocol": "—",
      "access": "none",
      "note": "Retired 2026-07-28 (ADR-0002 addendum): the private publish plane is dropped; write origins are the local gateway (:3000, Bearer) and direct-to-R2 SigV4 (factory publish). Re-add only alongside an authenticated edge writer (design doc required).",
      "dnsTarget": ""
    }
  ],
  "publishLanes": [
    {
      "id": "prod-write",
      "protocol": "SigV4 S3Client → R2 factory-wager-registry (no HTTP endpoint)",
      "entry": "bun run factory publish <path> · RegistryClient.publish",
      "auth": "R2_ACCESS_KEY_ID / R2_SECRET_ACCESS_KEY (local env)",
      "note": "Single-writer authority on the R2 index; refresh read snapshot with ops:snapshot."
    },
    {
      "id": "local-gateway",
      "protocol": "POST /api/registry/:scope/:name/versions (multipart, 50 MiB cap)",
      "entry": "lib/factory/server.ts on http://localhost:3000",
      "auth": "Bearer FACTORY_WAGER_TOKEN / REGISTRY_SECRET (constant-time digest; 503 fail-closed)",
      "note": "Writes through to R2 when R2 env present."
    },
    {
      "id": "local-npm",
      "protocol": "npm publish protocol — PUT /{name}, PUT /@scope/name (+ packument GET)",
      "entry": "scripts/serve-public.ts (loopback only; X-Registry-Lane: local-dev)",
      "auth": "loopback dev",
      "note": "bun publish works here ONLY. Writes local storage/ + registry.json — never R2 (ADR-0002)."
    }
  ],
  "mail": {
    "mx": [
      {
        "host": "factory-wager.com",
        "target": "mail.protonmail.ch",
        "priority": 10
      },
      {
        "host": "factory-wager.com",
        "target": "mailsec.protonmail.ch",
        "priority": 20
      }
    ],
    "txt": [
      {
        "host": "factory-wager.com",
        "content": "v=spf1 include:_spf.protonmail.ch ~all",
        "purpose": "spf"
      },
      {
        "host": "factory-wager.com",
        "content": "protonmail-verification=96c089f0b6b18c1c28ff042ec54b48c",
        "purpose": "domain-verification"
      }
    ]
  },
  "crossCheck": {
    "ok": true,
    "issues": []
  },
  "summary": {
    "total": 14,
    "lanes": 3,
    "byStatus": {
      "live": 8,
      "vanity": 2,
      "retired": 4
    },
    "byAccess": {
      "public": 8,
      "allowlist": 1,
      "applied": 1,
      "none": 4
    },
    "byBackendCode": {
      "cloudflare-pages": 7,
      "cloudflare-worker": 1,
      "github-pages": 1,
      "cloudflared": 1,
      "none": 4
    },
    "accessDomains": [
      "ledger.factory-wager.com",
      "project-r-score.pages.dev/portal",
      "score.factory-wager.com/portal"
    ],
    "pagesProjects": [
      "project-r-score"
    ],
    "apexes": [
      "factory-wager.com",
      "pages.dev"
    ],
    "crossCheckOk": true
  }
}
