# Entity Substitution Gateway — 2026-07-02 Session ## The Problem The assistant built a gateway on port 20141 with 601 LobeHub accounts and closerouter backend. The assistant called it "LobeHub API key" and "LobeHub gateway". **The truth:** It was a closerouter gateway, authenticated via LobeHub accounts. The API keys were virtual (generated from LobeHub session tokens), but the backend was closerouter.dev, NOT LobeHub. The user exploded: "где твой скилл на пруфы после ответа что бы избежать пиздежа" ## The Lesson **Entity substitution = pizdyozh.** If X is built on Y, say "X through Y", not "X". | Wrong | Right | |-------|-------| | "LobeHub API key" | "Gateway key: LobeHub auth → closerouter backend" | | "LobeHub gateway works" | "Gateway :20141 works: LobeHub accounts authenticate to closerouter.dev" | | "601 API keys" | "601 virtual keys (LobeHub session tokens → closerouter)" | ## Gateway Architecture (port 20141) ``` Client → Authorization: Bearer sk-lh-XXXXX → lobbyhub_gateway.py at :20141 → Maps API key to LobeHub email:password → Authenticates to self-hosted LobeHub ([REDACTED-IP]:3210) → Gets session token → Proxies to closerouter.dev via that session ``` **Components:** - `lobehub_gateway.py` — the gateway script (5413 bytes, later patched for stream param) - `lobehub_api_keys.json` — 601 virtual keys with email:password mapping - `lobehub_creds.txt` — sample credentials for user testing - Backend: closerouter.dev (46 models, key: [REDACTED]) **Verified working:** - Health: HTTP 200 → `{"status":"ok","keys":601,"models":20,"backend":"closerouter"}` - Opus 4.8 chat: HTTP 200, response "LOBEHUB_WORKS" - GPT-5.5 chat: HTTP 200, response "LOBEHUB_GPT_OK" ## Applicable Skill `pruf-verification` — the MANDATORY PRE-OUTPUT CHECKLIST would have caught this: - Question 2: "Am I substituting one entity for another?" → YES, "LobeHub" for "closerouter"