ADR-001: Runtime and hosting
Date: 2026-04-28 Status: Accepted
Context
Baseleg needs a lightweight hosting model suited to a small team, with a Cloudflare-friendly runtime for the product app and a simple way to publish documentation.
Decision
- The product app (
apps/web) will target the Cloudflare runtime. - Documentation (
apps/docs) will be published to GitHub Pages as a static site.
Consequences
- Runtime-specific bindings (e.g. D1) are isolated to infrastructure and app wiring.
- Docs publishing is decoupled from production deployments.
Alternatives considered
- Single deployable for both app and docs (tighter coupling)
- Other hosts/runtimes (would reduce alignment with D1/Workers)
Update (2026-08-21) — how deploys actually work
The original decision to publish apps/docs to GitHub Pages was never carried out. Discovered
while building issue #49 (automating D1 migrations): both apps/web and apps/docs deploy
via Cloudflare Pages’ own dashboard-configured GitHub integration — visible as the “Deploying
base-leg-app/base-leg-docs with Cloudflare Pages” bot comments on every PR. This git integration
triggers preview deploys on every branch/PR and a production deploy on every push to main,
entirely outside this repo’s tracked GitHub Actions workflows.
This was undocumented and had to be reverse-engineered from evidence: .github/workflows/ deploy-app.yml (now renamed db-migrate-remote.yml) ran “successfully” on every merge to
main for months while its only step was a literal echo "TODO: add Wrangler deploy step..." —
yet the site demonstrably updated on every merge (that’s what caused the 2026-08-12 outage, PR
#48: new code went live referencing a schema that was never migrated). Cloudflare Pages’ git
integration is the only mechanism consistent with that evidence.
Consequence for CI: GitHub Actions does not deploy either app, and should not try to —
db-migrate-remote.yml exists only to apply pending D1 migrations to production on push to
main (the one real gap Pages’ deploy doesn’t cover), using CLOUDFLARE_API_TOKEN/
CLOUDFLARE_ACCOUNT_ID repo secrets scoped to Account > D1 > Edit only — no Pages/Workers
deploy permission, since it never deploys anything.
Known residual risk, not solved: Pages’ deploy and db-migrate-remote.yml’s migration-apply
are two independent systems reacting to the same push to main, with no ordering guarantee
between them. In principle there’s a brief window where new code is live before its migration
has applied — a much smaller version of the original incident (which was migrations never
applying at all, not a sub-minute race). Closing this fully would mean either disabling Pages’
auto-deploy in favor of an Actions-orchestrated deploy+migrate sequence, or using a Cloudflare
Pages Deploy Hook to sequence the two — out of scope for issue #49 (NON_GOALS explicitly
excludes a multi-environment/orchestration pipeline); left as a known limitation.