| Layer | Choice | Why |
|---|---|---|
| Static site | Astro 5 | Pre-rendered HTML, MDX-driven content, zero runtime cost. |
| Styling | Tailwind v4 | CSS-first tokens; brand changes are a global swap. |
| Hosting | Cloudflare Pages (cr-ai-intranet) | Edge-deployed, integrated with the rest of CF. |
| Auth | Cloudflare Access | Google Workspace SSO at the edge, no in-app code. |
| Chat API | cr-ai-proxy Worker on cr-proxy.cannularobotics.com | Bearer-auth proxy that talks to Anthropic via AI Gateway. |
| AI Gateway | Cloudflare AI Gateway (cr-ai-gateway) | Rate limits, cost caps, request inspection. Auto-fallback to direct on 401. |
| Model | Claude Opus 4.7 with ZDR | Default. Sonnet/Haiku selectable per request. |
| Retrieval | cr-retrieval Worker on cr-retrieval.cannularobotics.com | RAG over Notion + Granola + Drive. |
| Embeddings | Workers AI @cf/baai/bge-large-en-v1.5 (1024-dim) | In-CF; cheap; swappable. |
| Vector store | Cloudflare Vectorize | One index per source: cr-notion, cr-granola, cr-drive. |
| Sync state | Cloudflare KV (cr-retrieval-sync-state) | Per-source cursors and high watermarks. |
| Notion access | Internal integration token + REST API directly | Workers-native fetch; no Node-shim libraries. |
| Drive access | Google OAuth refresh token | User-scoped, no service account, no domain-wide delegation. |
| Granola access | Drive-folder fallback | Granola exports notes into a Drive folder; we index from there. |
| Ingest | On-demand via POST /api/admin/ingest | Cron paused until workers.dev subdomain is registered. |
| Repo | github.com/sjolundjohn/cannula-ai-intranet | Monorepo (Astro site + two Workers). |
Everything lives in a single CR Cloudflare account, separate from any other tenant.