Gitea-native uptime probe. Reads .upptimerc.yml-compatible config,
emits per-site Result{timestamp, name, url, status_code, latency_ms,
success, error} as JSON. Optional -history-dir appends per-site JSONL
files for time-series.
Why: upptime is structurally GitHub-coupled (every code path hits
api.github.com — releases lookup + issue management + result commits).
Post the 2026-05-06 GitHub org suspension, no token in our org
authenticates there. Diagnosis + replacement options in
molecule-ai-status#2.
What this replaces vs deliberately leaves out:
- IN: probe loop, parallel HTTP, status + latency cap matching, JSONL
history append, JSON stdout output
- OUT: result commits (Gitea Actions cron orchestrates), issue
management (out of scope), status-page rendering (Vercel does that)
Module path: go.moleculesai.app/uptime-probe (vanity from day 1 — no
migration cost later; matches internal#71 pattern).
Smoke-tested against the existing .upptimerc.yml in molecule-ai-status:
all 7 production endpoints (canvas, docs, CP, landing) return 200 with
latencies 148-357ms. Probe classifies correctly.
Exit codes:
0 all probes succeeded
1 one or more sites returned a non-success (status / latency /
connection failure)
2 config error / unrecoverable I/O
|
||
|---|---|---|
| cmd/probe | ||
| go.mod | ||
| go.sum | ||
| README.md | ||
molecule-ai-uptime-probe
Gitea-native uptime monitor for Molecules AI services. Replaces upptime/uptime-monitor, which died post-2026-05-06 because every code path hits api.github.com and our org tokens no longer authenticate there.
Why
upptime/uptime-monitor is structurally GitHub-coupled:
- Calls
api.github.com/repos/upptime/uptime-monitor/releasesto look up its own version - Posts probe results as commits to the host repo via the GitHub API
- Manages incidents as GitHub Issues
- Generates a static site assuming GitHub Pages
After the 2026-05-06 GitHub org suspension, none of those calls authenticate. Per feedback_no_single_source_of_truth: vendor-neutral by design, runs on our own infra.
Design
┌─────────────────────────────────────────────────┐
│ This binary │
.upptimerc.yml ──▶ │ 1. parse config (upptime-compatible) │ ──▶ stdout: JSON
│ 2. probe each URL in parallel │
│ 3. emit Result{timestamp,name,url,latency, │ ──▶ history/<slug>.jsonl
│ status_code,success,error} │ (one line per check)
└─────────────────────────────────────────────────┘
▲ ▲
│ │
Gitea Actions cron (every 5m) molecule-ai-status repo's
runs `uptime-probe -config .upptimerc.yml` history/ directory; commits
appended on each cron run
│
▼
Vercel-deployed status page
@ status.moleculesai.app
reads history/ JSONL files
Three small things, each with one concern:
- This binary — read config, probe, emit results. No commit logic, no rendering, no alerting.
- Gitea Actions cron (lives in
molecule-ai-statusrepo) — schedule + commit + Vercel rebuild trigger. - Status page (a Next.js app on Vercel) — reads JSONL, renders charts.
Loose coupling = each piece can be replaced without touching the others. Probe binary becomes a Vercel cron? No commit history? Different SCM? — only the orchestration changes.
Usage
# Build
go build -o uptime-probe ./cmd/probe
# Run with default config
./uptime-probe -config .upptimerc.yml
# Run + append per-site history files
./uptime-probe -config .upptimerc.yml -history-dir ./history
# Custom probe timeout / concurrency
./uptime-probe -config .upptimerc.yml -timeout 10s -concurrency 16
Exit codes:
0— every probe succeeded1— one or more sites returned a non-success status (status-code mismatch, latency cap, or connection failure)2— config error or unrecoverable I/O
Config compatibility
The probe consumes the existing .upptimerc.yml shape so no migration is needed:
sites:
- name: Customer app
url: https://app.moleculesai.app
# optional fields:
expectedStatusCodes: [200, 201] # default: 200..208, 226
method: GET # default: GET
maxResponseTime: 3000 # ms, default: no cap
headers:
- "Origin: https://moleculesai.app"
Top-level upptime keys we ignore (owner, repo, status-website, theme, etc.) stay benign — the probe doesn't care.
What this binary deliberately doesn't do
- Talk to
api.github.com. The whole point. - Manage issues / commits / status badges. Out-of-band orchestration concerns.
- Render the status page. Vercel-deployed Next.js does that.
Install via vanity path
go install go.moleculesai.app/uptime-probe/cmd/probe@latest
Resolves via the go.moleculesai.app vanity responder (issue molecule-ai/internal#71) → Gitea repo (here).
Tracking
- Replacement plan:
molecule-ai/molecule-ai-status#2 - Vanity import migration:
molecule-ai/internal#71 - License: same as parent (TBD by org default)