Keep the runner where OneDrive already lives. Move the public surface, the run log, and the served archive to Cloudflare. Cost stays inside the free tier; the Mac stops being load-bearing for any external observer.
monthly run-rate cost
$0–4/ mo
R2 + D1 + Workers stay free at this volume. Mac runs on existing hardware.
OneDrive rewrite
0lines
Hybrid keeps OneDrive sync via the local filesystem. No Microsoft Graph build.
public availability
≈100%CF edge
API + run log + archive served from Cloudflare. Mac downtime ≠ user downtime.
Create cca-research-archive on R2. Add a Mac-side r2-archiver that copies filed PDFs after each successful run. Public-but-CF-Access-gated read URL.
One wrangler r2 bucket create
One small Python uploader, hooked into the existing post-run callback
Mac stays canonical — R2 is just a mirror
Phase 2 · ~1 hr
low riskwrites data
D1 run-log mirror
Create grenamer_runs table on D1. Add a d1-syncer that pushes new rows + tail logs every minute. Worker exposes GET /runs backed by D1 instead of the tunnel.
Schema mirrors local SQLite 1:1
Sync is one-way (Mac → D1)
Status calls stop depending on the Mac being up
Phase 3 · ~2 hr
mediumreplaces tunnel-only path
Worker as primary API
Rebuild POST /run on the Worker itself: write to D1, push a Queue message, Tunnel delivers to Mac. Keep current direct-tunnel route as a backup. Add grenamer.ccaresearch.com dashboard.
API surface no longer requires Mac uptime to respond
Queue gives debounce + retry + DLQ for free
Browser dashboard with live feed + trigger button
Cost · expected free-tier headroom
Service
Free tier
Expected use
$/mo at 10×
Workers
100k req/day
~50 req/day
$0.00
D1
5 GB · 5M reads/day
<100 MB · ~1k reads/day
$0.00
R2 storage
10 GB
~5 GB (12 mo of PDFs)
$0.00
R2 Class A ops
1M / mo
~3k / mo
$0.00
R2 egress
unlimited
whatever the team views
$0.00 no egress fees
Queues
1M ops / mo
<5k / mo
$0.00
Pages
unlimited static
one site
$0.00
Tunnel
already running
unchanged
$0.00
Gemini API
budget already set
unchanged
— existing
What you keep
OneDrive as the canonical filesystem — no Microsoft Graph rewrite
Existing Mac-side Python + SQLite + launchd jobs run unchanged
Sentinel-file trigger fallback stays in place
Bearer-token API + ChatGPT Action keeps working through the migration
What you gain
Public surface decoupled from Mac uptime — status endpoint always answers
Searchable PDF archive at a CF Access-gated URL the team can hit
Run log queryable from anywhere, not just the M4E volume
One tunnel-down event no longer means "no grenamer for the day"
Risks worth flagging
D1 ↔ SQLite drift. Mac-side SQLite stays canonical; D1 is read-only mirror. Drift is recoverable by re-pushing.
R2 archive permissions. Default to CF Access gate; never enable a public R2 bucket with broker PDFs.
Queue-bypass during migration. Keep the direct-tunnel POST path live until Phase 3 is verified for ≥1 week.
Gemini cost. Unchanged — same calls, same volume. No new spend.