build log
📓 build log · april 13, 2026

cv intel build log — edge-native civic intelligence

cvintel.org is live. cloudflare workers + d1, astro v6, speed 0 cron ingestion from primegov, 33 seeded records, zero external dependencies in the markdown renderer.

cvintel.org is live. a cloudflare workers + d1 application serving server-rendered astro pages at the edge — zero cold start, no node.js server, no github middleman.

the deploy pipeline was nontrivial. astro v6 with the @astrojs/cloudflare v13 adapter generates a workers with assets bundle, not a pages deployment. discovered that wrangler pages deploy silently drops the worker script, and that running wrangler deploy from within the project tree causes a config path conflict with .wrangler/deploy/config.json. resolved both: the canonical deploy is cd /tmp && npx wrangler deploy --config ~/Projects/cvintel-web/dist/server/wrangler.json, wrapped in an npm script.

database seeded. a python import script parsed 33 rancho mirage civic intelligence records from markdown — handling two inconsistent date formats across 18 months of meeting files — and generated clean sql. all 33 records are live in the remote cloudflare d1 database as status='draft', confidence='flash', waiting for editorial review.

full editorial loop working. /desk shows the draft queue. each record links to its public page at /briefs/[city]/[slug]. the record page renders markdown through an inline converter written from scratch — no external dependencies, workers runtime compatible. handles headings, lists, tables, bold, code, links, horizontal rules. draft records show an amber banner and noindex. published records show clean output with a publication dateline.

speed 0 cron worker deployed. a separate cloudflare worker (cvintel-cron) runs daily at 14:00 utc. it hits the palm springs primegov public api, pulls upcoming meetings, deduplicates against d1 by a deterministic record id (YYYY-MM-DD--city-slug--body-slug), calls claude haiku for a two-paragraph plain-language preview of each new meeting, and writes the result to d1 as a draft. tested locally: fetch, write, dedup all confirmed. deployed to production and triggered manually — inserted: 1 on first run, skipped_duplicate: 1 on second. the palm springs planning commission meeting of april 15 is now in the draft queue.

what was investigated and ruled out: agendaLink requires jwt bearer auth on all document endpoints — shelved. primegov document downloads are spa-gated — the speed 0 worker uses meeting metadata as the signal without downloading content.

numbers: 33 civic intelligence records in production d1 · 1 speed 0 record auto-generated on first production run · 2 cloudflare workers deployed · 0 external dependencies in the markdown renderer · 0 github actions in the deploy pipeline.

tools: claude, claude code, astro v6, cloudflare workers, cloudflare d1, cloudflare pages, primegov api, claude haiku, wrangler, python.