Maintained by Megabyte Labs · built by Brian Zalewski
One sensor. One signal. One hotline. A free public API for EMF, entropy, and the unfiltered record of being followed.
- Overview
- Why This Exists
- Quick Start
- The API
- Architecture
- Local Development
- Testing
- Deploying
- The Hotline
- The Dossier
- Stack
- References
- Contributing
- License
Ghost Signal is a public-record + entropy-science project hosted entirely on Cloudflare Workers. It exposes a single GQ EMF-390 sensor (wired into Home Assistant) through a free, rate-limited, edge-cached API; a Claude-powered AI chat; a Twilio voice hotline at (601) 666-6602; a transmissions archive of every call; and a multimedia dossier of unexplained life events.
The project ships three pillars:
| Pillar | What it is | Why it exists |
|---|---|---|
| Public sensor | GQ EMF-390 streaming EMF / EF / RF readings via Home Assistant → Worker → Cache | Anyone can poll, graph, audit, or build on real environmental EM data |
| Entropy AI | True random numbers harvested from a living electromagnetic field | Entropy no algorithm can fake — fit for CS, physics, and AI experiments |
| Public record | Multimedia dossier + AI hotline + transmission archive | Disclosure on the operator's terms — facts that would surface anyway |
Ghost Signal is intended for:
- Researchers who want a free, rate-limited, OpenAPI-documented public EMF feed
- Cryptographers and ML engineers who need entropy that no algorithm can fake
- Journalists and skeptics who want the raw, unfiltered record of an unusual life
- Anyone with a story who wants their own pattern of phenomena added to the file
- Builders who appreciate a working reference for Workers + Hono + D1 + KV + Twilio + Claude
The operator (Brian Zalewski, B.S. Aerospace Engineering / Applied Sciences, Rutgers '11) has spent more than a decade as a senior software architect and another decade documenting an unrelenting pattern of phenomena: orbs, cellular SSIDs renamed to taunt research subjects, time-traveler-grade coincidences, possessions, exorcisms, EMF spikes that map to events, and a hotline of voicemails that should not exist. Rather than keep the file private, the file ships as a website, a public API, and a phone number.
Every reading, transcript, and entropy byte is permanent public record. If something is happening, the data is part of the case file. If nothing is happening, that's a case file too.
No keys. No accounts. Sixty requests per minute per IP.
# Read the current EMF (mG) sensor value
curl https://ghost.megabyte.space/api/v1/current
# Pull the last 24h of history
curl 'https://ghost.megabyte.space/api/v1/history?hours=24'
# Mint 256 true-entropy random integers in [0, 65535]
curl 'https://ghost.megabyte.space/api/v1/random?count=256&min=0&max=65535'
# Browse the Swagger UI
open https://ghost.megabyte.space/api/docsTo run a local mirror against the production Worker code:
git clone https://github.com/megabyte-labs/ghost.megabyte.space.git
cd ghost.megabyte.space
pnpm install
cp .dev.vars.example .dev.vars
pnpm devThe formal OpenAPI 3.1 spec lives at /api/v1/openapi.json. Browse the Swagger UI or the hand-written docs.
| Method | Path | Purpose | Cache TTL |
|---|---|---|---|
GET |
/api/v1/health |
Liveness + version + timestamp | none |
GET |
/api/v1/meta |
Sensor metadata, started-at, units, rate limit | 60s |
GET |
/api/v1/current |
Latest single reading | 2s |
GET |
/api/v1/sensors |
All EMF / EF / RF families at once | 2s |
GET |
/api/v1/history |
Time-windowed series (hours, from, to, step) |
15s |
GET |
/api/v1/entropy |
Entropy summary (mean, variance, peak, deltas) | 15s |
GET |
/api/v1/snapshot |
Raw D1 snapshot rows | 15s |
GET |
/api/v1/export |
CSV / NDJSON bulk export | 30s |
GET |
/api/v1/google-sheets |
Sheets-friendly TSV stream | 30s |
GET |
/api/v1/random |
True-random integers from live entropy | none |
GET |
/api/v1/timeline |
Curated timeline of dossier events | 300s |
GET |
/api/v1/transmissions |
Hotline call transcript index | 60s |
GET |
/api/v1/transmissions/live |
Server-sent stream of new transcripts | n/a |
GET |
/api/v1/transmission-count |
Total recorded calls | 60s |
POST |
/api/v1/chat |
Ghost Signal AI chat (Claude Sonnet) | n/a |
POST |
/api/v1/debate |
Two-agent debate stream | n/a |
POST |
/api/v1/newsletter/subscribe |
Subscribe via email | n/a |
POST |
/api/v1/twilio/voice |
TwiML entrypoint for incoming calls | n/a |
POST |
/api/v1/twilio/gather |
TwiML speech-gather webhook | n/a |
POST |
/api/v1/twilio/status |
TwiML completion / recording webhook | n/a |
GET |
/ws/mud |
WebSocket bridge into the public MUD | n/a |
| Family | Source entity | Unit | Typical range | Description |
|---|---|---|---|---|
| EMF | sensor.gq_emf390_emf_mg |
mG (milligauss) | 0–3000+ | Magnetic field strength — the headline number on the chart |
| EF | sensor.gq_emf390_ef_v_m |
V/m | 0–1000+ | Electric field strength |
| RF | sensor.gq_emf390_rf_total_density_mw_m2 |
mW/m² | 0–200+ | Total radio-frequency power density |
Rate limit: 60 requests / minute / IP (KV-backed sliding window)
Cache: Cloudflare Cache API at the edge
Headers: ETag, Last-Modified, Cache-Control: public,max-age=<TTL>
Origin: Worker -> Home Assistant -> GQ EMF-390 USB
| Tier | Latency budget | Notes |
|---|---|---|
| Edge cache hit | < 30 ms | Near-100% on /current and /sensors during steady traffic |
| Worker cold path | 50–200 ms | Fetch from Home Assistant + bundle response |
| Hotline call | 1.4–2.2 s round-trip | Twilio + Claude Haiku, optimized for voice |
# Last 6 hours, 60-second buckets
curl 'https://ghost.megabyte.space/api/v1/history?hours=6&step=60'
# Entropy distribution since project start
curl 'https://ghost.megabyte.space/api/v1/entropy?from=2026-04-03'
# Pure CSV stream for spreadsheets
curl -o emf.csv 'https://ghost.megabyte.space/api/v1/export?format=csv&hours=24'
# 16-byte hex true-random token
curl 'https://ghost.megabyte.space/api/v1/random?bytes=16&format=hex'// JavaScript: poll /current at 2s
async function tick() {
const r = await fetch("https://ghost.megabyte.space/api/v1/current");
const { value, unit, timestamp } = await r.json();
console.log(`${timestamp} ${value} ${unit}`);
}
setInterval(tick, 2000);# Python: bulk export to a DataFrame
import pandas as pd
df = pd.read_csv("https://ghost.megabyte.space/api/v1/export?format=csv&hours=168")
print(df.describe()) (60 rpm / IP)
+----------+ +-----------------+ +--------------------+
client -| Edge |------> | Worker (Hono) |------> | Home Assistant |
| cache | HIT | - Zod validate | miss | GQ EMF-390 (USB) |
+----------+ | - Rate-limit | +--------------------+
^ | - Cache write | |
| | - D1 snapshot | |
+------ <-----+ - KV counters | |
+-----------------+ |
| | |
v v |
D1 KV |
(snapshots) (rate-limit + entropy seed)
|
Twilio (voice) <-> Claude Haiku/Sonnet
|
Browser (xterm.js MUD) <-> /ws/mud
| Endpoint | TTL | Why |
|---|---|---|
/api/v1/current |
2 s | Real-time enough for charts; cheap on misses |
/api/v1/sensors |
2 s | Fan-out across families needs to stay fresh |
/api/v1/history |
15 s | Bucketed series tolerates short staleness |
/api/v1/entropy |
15 s | Recomputed against latest 15s of readings |
/api/v1/random |
0 s | Never cache — defeats true-randomness |
/api/v1/timeline |
300 s | Curated content, rarely changes |
| Binding | Type | Purpose |
|---|---|---|
ASSETS |
Cloudflare Assets | Static public/ directory |
EMF_DB |
D1 | Snapshot history, transcripts, newsletter, debate logs |
RATE_LIMIT_KV |
KV | Per-IP sliding-window counters + entropy seed |
AI |
Workers AI | Claude Haiku fallback for chat persona |
# Install
pnpm install
# Configure
cp .dev.vars.example .dev.vars
# Type-check + start dev server (auto-reload on save)
pnpm check
pnpm devThe dev server runs at http://127.0.0.1:8787/. The Worker reads from a local mock unless EMF_SENSOR_HASS_URL and EMF_SENSOR_HASS_TOKEN are set in .dev.vars.
| Variable | Description | Default |
|---|---|---|
EMF_SENSOR_HASS_URL |
Home Assistant base URL | unset (mock mode) |
EMF_SENSOR_HASS_TOKEN |
Home Assistant long-lived access token | unset |
EMF_SENSOR_ENTITY_ID |
EMF magnitude entity in Home Assistant | sensor.gq_emf390_emf_mg |
EF_SENSOR_ENTITY_ID |
Electric-field entity | sensor.gq_emf390_ef_v_m |
RF_SENSOR_ENTITY_ID |
RF density entity | sensor.gq_emf390_rf_total_density_mw_m2 |
EMF_SENSOR_STARTED_AT |
ISO timestamp the public record began | 2026-04-03T02:47:58.394637+00:00 |
CURRENT_CACHE_TTL_SECONDS |
Cache TTL for /current and /sensors |
2 |
HISTORY_CACHE_TTL_SECONDS |
Cache TTL for /history |
15 |
ENTROPY_CACHE_TTL_SECONDS |
Cache TTL for /entropy |
15 |
PUBLIC_API_RATE_LIMIT_PER_MINUTE |
Per-IP request budget | 60 |
ANTHROPIC_API_KEY |
Claude key for chat / hotline | unset (uses Workers AI fallback) |
TWILIO_AUTH_TOKEN |
Twilio webhook signature secret | unset |
RESEND_API_KEY |
Newsletter sender | unset |
For the full list, see src/types.ts Env interface.
# Full Playwright E2E suite (multi-feature flows, 6 breakpoints)
pnpm test:e2e
# Headed run
pnpm test:e2e:headed
# Open last HTML report
pnpm test:e2e:reportLocal E2E uses a committed mock env at .dev.vars.playwright, runs the Worker in deterministic mock-sensor mode, enables dev-only __test/seed + __test/reset helpers, and writes state to .wrangler/state/e2e. Tests are stateful and accumulate — never deleted, only appended.
| Suite | Coverage | Breakpoints |
|---|---|---|
journey.spec.ts |
Full homepage walkthrough — click, type, scroll, chat | 375, 390, 768, 1024, 1280, 1920 |
api.spec.ts |
Every documented endpoint + error envelope shape | n/a |
hotline.spec.ts |
TwiML round-trip via mock Twilio webhook | n/a |
entropy.spec.ts |
Distribution sanity checks on /random |
n/a |
# Deploy to production (custom domain ghost.megabyte.space)
pnpm deploy
# Roll back the last deployment
pnpm wrangler rollback
# Tail live production logs
pnpm wrangler tail --env production --format=jsonCache purge after content changes:
curl -X POST \
"https://api.cloudflare.com/client/v4/zones/$ZONE_ID/purge_cache" \
-H "X-Auth-Email: $CF_EMAIL" \
-H "X-Auth-Key: $CF_KEY" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'See DEPLOY.md for the full runbook, secrets handling, and rollback playbook.
Call (601) 666-6602 from any phone. The call is answered by an AI persona running on Claude Haiku, recorded, transcribed, and published as a permanent transmission at /transmissions. By calling, you consent to all of that.
| Step | What happens |
|---|---|
| 1 | Twilio answers and POSTs to /api/v1/twilio/voice |
| 2 | Worker streams a TwiML <Gather input="speech"> |
| 3 | Caller's audio is transcribed by Twilio |
| 4 | Transcript is sent to Claude Haiku for the response |
| 5 | TwiML <Say> plays the AI reply, then re-gathers |
| 6 | On hangup, /api/v1/twilio/status finalizes the record + writes D1 + sends notification |
Every section on the homepage is part of a public file. The dossier currently covers:
- The first 280 mG alarm at a Rutgers nanostructures lab
- "Radiation TDR" / "Radiation TDS" cellular SSIDs broadcast by nearby cell towers
- Celestial hallucinations — orbs, parted clouds, the Atlanta layover
- The 666 rock at the lake
- Father Mark and the rejected exorcism
- St. John's Soup Kitchen — reality editing in real time
- Jungle Habitat — the dead battery in the haunted safari
- The Volume Hack and the middle-finger cursor
- Time-traveler encounters and the high-order angel saying, "Tell your story"
- The Hobbits — a monthly gathering of geniuses with
4 GONDORplates - Funny Books — suspected MIB dispersal location
If you have your own pattern of phenomena, the hotline takes calls.
| Layer | Technology |
|---|---|
| Edge runtime | Cloudflare Workers |
| Web framework | Hono + @hono/zod-openapi + @hono/swagger-ui |
| Static assets | Cloudflare Assets (public/) |
| Database | Cloudflare D1 (snapshots, transcripts, newsletter, debate logs) |
| KV | Cloudflare KV (rate limit counters + entropy seed) |
| Sensor upstream | Home Assistant ↔ GQ EMF-390 |
| Voice / SMS | Twilio Voice |
| AI | Anthropic Claude Sonnet (chat) + Haiku (voice) with Workers AI fallback |
| Frontend | Vanilla TypeScript + xterm.js for the in-browser MUD |
| Newsletter | Resend |
| Build / package manager | pnpm + Wrangler |
| Testing | Playwright v1.59+ multi-bp E2E |
| Observability | Sentry + PostHog + GA4 |
- Hono — tiny, fast Workers framework
- @hono/zod-openapi — OpenAPI 3.1 generator
- @hono/swagger-ui — Swagger UI middleware
- Cloudflare Workers — serverless edge runtime
- Cloudflare D1 — serverless SQLite at the edge
- Cloudflare Cache API — per-Worker cache control
- Home Assistant REST API — sensor source of truth
- GQ EMF-390 — the actual hardware
- Twilio Voice TwiML — hotline orchestration
- Anthropic Claude — chat + voice persona
- Playwright — E2E harness, AI healer, multi-bp
- xterm.js — MUD terminal in the browser
Contributions, issues, and feature requests are welcome. Open an issue first if the change is non-trivial. The project follows the Emdash OS v6.0 workflow — TDD, real-user E2E, deploy-then-purge, no console errors, no shortcuts. Stale docs are bugs. PRs that fix doc rot are loved.
| Channel | Where |
|---|---|
| Issues | github.com/megabyte-labs/ghost.megabyte.space/issues |
| hey@megabyte.space | |
| Hotline | (601) 666-6602 |
| Newsletter | Subscribe on the homepage |
Sponsorship
Dear Awesome Person,
I create open source projects out of love. Although I have a job, shelter, and as much fast food as I can handle, it would still be pretty cool to be appreciated by the community for something I have spent a lot of time and money on. Please consider sponsoring me. Who knows? Maybe I'll be able to quit my job and publish open source full time.
Sincerely,
Brian Zalewski
Copyright © 2024–2026 Brian Zalewski / Megabyte LLC. The Lesson License — read LICENSE before you build on this. The signal pre-dates the software.
