Appearance
Proxy Rotation
FreshSource: BIBLE.md (Phase 11 Cookie Refresh + Proxy Pool Fallback), bible/glossary.md (proxy marriage)
Ghost Engine uses two distinct proxy patterns: per-account "marriages" and a session pool for fallback.
Proxy marriage
Permanent 1:1 binding of a proxy IP to a persona. Never changes. Stored in proxy-marriages.json.
Why permanent: an account's IP is part of its identity. If someone@gmail.com always connects from 1.2.3.4, that's a coherent signal. If the IP changes weekly, every login looks like an attack to the platform.
Proxy pool fallback
When an account's married proxy gets rejected (Google says "signin/rejected", "blocked", or "unusual activity"), Ghost Engine pulls fresh session proxies from a pool.
data/proxy-pool.json contains 100 pg.proxi.es session proxies (F2K9t1gNVvNAxEVf-co-USA). Each new connection gets a different IP. Pool loaded at plugin startup via ProxyPool from core/proxy-rotate.mjs.
Recovery flow
flowchart TD S[Account login attempt] --> M[Married proxy] M -- ok --> D[Done: refresh cookies] M -- rejected --> P1[Pool proxy #1, fresh session id] P1 -- ok --> D P1 -- rejected --> P2[Pool proxy #2, fresh session id] P2 -- ok --> D P2 -- rejected --> P3[Pool proxy #3, fresh session id] P3 -- ok --> D P3 -- rejected --> Q[Quarantine account]
Each retry appends a random session ID (-sid-XXXXX) to the username for fresh IP.
Where it kicks in
The cookie-refresh plugin uses this flow:
- Launch browser with saved cookies, check if still logged in
- If logged in: re-capture fresh cookies, done
- If expired: call
loginPersona(persona)orjoinPlatform(persona, platform)(randomized 65% OAuth, 35% direct) - If proxy rejected: pull fresh proxy from pool
- Up to 3 retries from pool
- If all fail: quarantine
Proxy manager plugin
plugins/proxy-manager/ wraps core/proxy-rotate.mjs ProxyPool. 7 routes:
| Method | Route | What |
|---|---|---|
| GET | /proxies | List proxies |
| POST | /proxies | Add proxy |
| DELETE | /proxies/:id | Remove |
| POST | /proxies/:id/health-check | Test connection |
| GET | /proxies/health | Pool health stats |
| POST | /proxies/rotate | Force rotate |
| POST | /proxies/assign | Assign to account |
Pool health route
bash
curl http://localhost:4700/cookies/proxy-poolReturns { alive, dead, total }.
Health-aware rotation
The ProxyPool tracks per-proxy health:
- 200 OK on test fetch: +1
- timeout/refused/4xx/5xx: -1
- Score below threshold: removed from active pool
When pulling a proxy from the pool, the manager picks the highest-health unused one first.
Per-account fingerprint + proxy + timezone consistency
The full identity stack ensures consistency:
flowchart LR E[Account email] --> M[Proxy marriage 1.2.3.4] M --> G[Geo: Dallas, TX] G --> TZ[Timezone: America/Chicago] G --> LA[Language: en-US] G --> UULE[UULE: Dallas, TX] E --> FP[Fingerprint deterministic from email hash]
Sleeve network-identity.mjs enforces this:
- Proxy marriage permanent
- Timezone from geo
- Language from country
- WebRTC and DNS leak protection