Every decision we made, and why. The goal: climb to Stage 5 (AI-Native) of GTM maturity
fast — by integrating best-of-breed open-source software on a VPS fronted by Cloudflare, unified by a thin
custom cockpit and operated by the best AI skill libraries. We build the connective tissue; we don't rebuild the CRM.
RECORD DATE · JUNE 2026REPO · ~/business-os (2 commits)VERIFIED · full stack boots, all web apps 200
The vision
DECISION 01 · STRATEGY
Reach Stage 5 (AI-Native) by integrating OSS, not coding from scratch
Where great open-source exists (CRM, BI, workflow), adopt it. Spend the build budget only on the
glue + the AI layer. Operating backbone fused from four books: Traction/EOS, Get Scalable, The High Growth Handbook,
Unreasonable Hospitality.
enterprise-gradefast-to-value
DECISION 02 · APPROACH
Harvest the best of what's already built — extend, don't restart
Reuse the GTM engine (prospect.py, 135 prospects), the knowledge spine
(knowledge.db, 369 docs), the gold/dark design system, and the company-brain VPS pattern.
The new repo is the connective tissue over these.
reuseone source of truth
Architecture & scope
DECISION 03 · HOST
A real VPS fronted by Cloudflare — not Cloudflare-native
The stack is persistent, stateful, multi-service Docker — VPS-shaped. Cloudflare's compute is
serverless (Workers = ms CPU; Containers = small, scale-to-zero), so running off-the-shelf OSS there would mean
re-platforming everything. A flat VPS is cheaper for always-on and lets us add RAM by rebooting. Cloudflare does the
free, secure edge: Tunnel (no inbound ports) + Access (email/PIN gating).
VPS + Cloudflarevs Workers/Containers
DECISION 04 · FOOTPRINT
Ship a lean core first, expand later
v1 = CRM + BI + workflow + scheduling + the cockpit (~6GB, fits a 16GB box). Helpdesk, email
marketing, client portals come in Phase 2. Fastest path to a working OS over "stand up everything at once."
lean core
DECISION 05 · AUDIENCE
Build the internal cockpit first; client portals are Phase 2
Matches "internally facing," and keeps it single-tenant (simpler auth, cleaner n8n licensing) until
the engine is proven.
internal-first
DECISION 06 · FRAMEWORKS
EOS cadence first, then layer the other three books
Build the operating heartbeat now: Scorecard (→ Metabase), Rocks (quarterly),
weekly L10. Get Scalable's value-engine becomes CRM pipeline stages; Gil's scaling playbooks live in the KB;
Guidara's hospitality becomes delight checkpoints in client-delivery workflows.
EOS heartbeat
The stack we chose
Best-of-breed, self-hostable, integration-friendly. n8n is the spine everything webhooks through.
Role
Pick
Why
CRM
EspoCRM
light, full REST API (MariaDB)
BI / Scorecard
Metabase
dashboards = the EOS Scorecard surface (Postgres)
Workflow
n8n
the integration spine; native Cal.com node
Scheduling
Cal.com
booking → n8n → CRM
Command center
cockpit
the part we build; unifies it all
Licensing calls
AGPL is fine behind Access — copyleft only triggers on external distribution of modified code.
n8n is free for our automations & building client flows; to host clients' own workflows later, swap to Activepieces (MIT).
Skill libraries
marketingskills · CRO, copy, email, ads
claude-seo · local SEO + GEO/AEO (the niche)
sales · ICP → sequences, CRM connectors
Installed via npx skills behind a security-audit gate.
Implementation calls
DECISION 07 · COCKPIT
Zero-dependency Python (stdlib + HTMX), not FastAPI
Matches the existing Jake-OS ethos, makes the container tiny, and runs locally for instant
verification. Six modules — Home · Pipeline · Scorecard · Knowledge · Cadence · Apps — in the gold/dark design,
reading the real prospect registry & knowledge base. Can graduate to FastAPI later.
stdlib + HTMXvs FastAPI
DECISION 08 · ROUTING & DATA
cloudflared maps hostnames → services (no Caddy); two databases
TLS terminates at Cloudflare; the tunnel routes each hostname to a container — one fewer moving part.
Postgres for n8n/Metabase/Cal.com; MariaDB for EspoCRM; cockpit state in its own SQLite. Data (prospects + knowledge)
stays sourced on the laptop and syncs to the box read-only.
no CaddyPG + MariaDB
DECISION 09 · VERIFY
Proved it boots — and fixed a real bug before the VPS
Brought the full stack up locally: all 8 services run, all 4 web apps return 200,
Postgres auto-creates each app's database. The test caught a bind-mount permission bug (init scripts unreadable under
rootless podman/SELinux) — fixed with the z relabel flag, harmless on the Debian/Docker VPS.
verifiedbug fixed
The hosting pivot
DECISION 10 · PROVIDER
Hetzner demanded a passport → switched to Contabo
Hetzner's KYC blocked signup. Contabo is the closest match — cheap, big RAM, NVMe, a Seattle
data center near Pocatello, and card-only verification. DigitalOcean is the smoothest fallback. Because the
whole stack is just Docker-on-Linux behind Cloudflare, switching providers changes one file
(create-server.sh) — nothing else.