Infrastructure & Operations
Category: operations Sources: digital-home-standup skill output, live production verification (2026-08-09, re-verified 2026-08-11), digital-home-manifest.json (trace-backend repo) Confidence: high Last Updated: 2026-08-11
Where things actually run, and where their secrets live. Written after a folder rename nearly broke the production build because none of this was recorded anywhere — this article exists so that never happens again.
The two repos
Trace's digital home is split across two separate git repositories with separate histories, deploy targets, and secrets:
This repo (brand-wiki) |
trace-backend |
|
|---|---|---|
| Contains | digital-home/frontend/ (the public site) + the entire brand wiki |
The CRM: pipeline, email sequences, funnel analytics, Cal.com bookings, AI content pipeline |
| Location | This monorepo | C:\Users\gmasc\dev\trace-backend, pushed to glenmascall/trace-backend (private) |
| Deploys as | Cloudflare Pages project brand-wiki (confusing name — it is the frontend deploy, not the wiki) |
Cloudflare Worker trace-backend |
| Deploy config | Root directory digital-home/frontend, output _site, build npm ci && npm run build, production branch master, auto-deploy on |
wrangler deploy; also runs a scheduled GitHub Action every 10 minutes to tick the email engine |
| Live at | tracetechnical.co.uk |
https://trace-backend.glen-6bf.workers.dev |
The backend is deliberately kept separate — own git history, own deploy target, own secrets. See digital-home-manifest.json in the trace-backend repo for the full installed/verified/pending state; a future session picking up backend work should start there.
Database
Supabase project trace-digital-home, ref bmoxvsntomudxggonfqe, region eu-west-2 (London).
Where secrets live
| Secret type | Where |
|---|---|
Site build variables (SUPABASE_URL, SUPABASE_ANON_KEY) |
Cloudflare Pages → project brand-wiki → environment variables, as plain text, not "secrets" — Cloudflare does not expose Pages secrets to the build step, only plain-text variables. Needed on both Production and Preview. Without them the build logs a warning and Field Notes renders as its empty state. |
| Worker secrets (capture key, etc.) | wrangler secret against the trace-backend Worker |
| CRM capture keys | backend_settings table |
What's live (verified 2026-08-09)
- Every form on the site files leads into the CRM — tagged, filed into the pipeline, with a deal auto-created in GBP. Verified in production:
{ok:true,emailed:true,captured:true,degraded:false} - Field Notes mailing list capturing with a recorded consent trail (single opt-in; see
functions/api/subscribe.jsand Website) - Cal.com bookings syncing — verified with a signed delivery accepted and a forged one rejected
- Email engine ticking every 10 minutes via GitHub Actions
brand_contextseeded from this wiki — 17 rows, ~71k characters, refreshed by thecompile-brainskill- DMARC live with a reporting address
- Pages build variables are set on Production — confirmed indirectly on 2026-08-11 because Field Notes and Guides render live from Supabase (six Field Notes, four Guides); without the variables the build would fall back to its empty state
- New Trace logo system deployed (Trace Technical wordmark + Guiding Progress mark);
sitemap.xmllive (22 URLs);robots.txtreturns 200 and opens the site to search (Allow: /) crm_safe_modeis ON — every email send is simulated. Nothing reaches a prospect until this is switched off by hand in/crm/settings. Read a simulated send before switching it off.
Still to wire (none of these block launch)
| Item | What it needs |
|---|---|
| Deploy hook for published notes | Create in Cloudflare Pages → Settings → Deploy Hooks (branch master), then a backend code change to call it on publish — the backend currently has no deploy-hook support at all. Until wired, a newly published note only appears on the site after the next deploy. |
RESEND_WEBHOOK_SECRET |
No Resend webhook exists yet, so bounces/opens/clicks are not ingested |
| CRM → Resend Audience sync | Subscribers land in the CRM; Broadcasts sends to a Resend Audience. Manual export/import for now — automate once the list grows |
| Double opt-in for Field Notes | Current sign-up is single opt-in with a recorded consent trail (defensible under UK GDPR/PECR). Double opt-in is stronger; needs a token, a confirm endpoint, and an email |
To review before full go-live
crm_safe_modeis still ON (see What's live). This is the real gate for outbound email: leads are captured and deals created, but every send is simulated until it is switched off by hand in/crm/settings. Read a simulated send before switching it off.- Allow AI crawlers (decided 2026-08-11; action in the Cloudflare dashboard). The site is to be open to AI crawlers for AI-search visibility. The block is Cloudflare's Managed robots.txt, not the repo
robots.txt(which is alreadyAllow: /), so it is removed in the Cloudflare dashboard: zonetracetechnical.co.uk→ AI Crawl Control / Manage robots.txt (and any Block-AI-bots managed rule) → disable, so the injectedDisallowfor ClaudeBot, GPTBot, Google-Extended, CCBot, Bytespider, Amazonbot, Applebot-Extended and meta-externalagent, and theai-train=nosignal, are dropped. No repo change needed. llms.txtis absent (404). Now that the site is opening to AI crawlers, worth adding.- Canonical host is www; apex 301s to www (live, verified 2026-08-11). The whole site canonicalises to
www.tracetechnical.co.uk(site.urlineleventy.config.js, the injected canonical,og:url, JSON-LD and all 22 sitemap URLs). The apex→www 301 runs fromdigital-home/frontend/functions/_middleware.js: a Pages_redirectsrule cannot match on hostname, so the middleware handles it (www and/api/*pass through vianext()). Verifiedtracetechnical.co.uk→ 301 →www.tracetechnical.co.uk. (Flipping canonical to the bare apex instead would be a larger change:site.url, the canonical injection,article.njkschema,robots.txt, plus a www→apex redirect.)
How to send a newsletter
/crm/leads→ filter tagnewsletter→ export- Resend → Audiences → create
Field Notes→ import - Resend → Broadcasts → New → pick that audience
- Write it, from
hello@tracetechnical.co.uk - Test send to yourself, check on a phone
- Send
Resend adds and honours the unsubscribe link on Broadcasts automatically. Don't use the CRM's sequences for this — those are for timed per-person sequences, not one-to-many sends, and safe mode is on regardless.
Write the first newsletter yourself, not AI-drafted. brand_context is strong enough for a good AI draft, but the first thing a list ever receives sets the expectation for everything after, and Trace's positioning is explicitly anti-filler.
Known upstream faults (BraveBrand starter, not Trace-specific)
Both patched locally — flagging here so a future rebuild or starter upgrade doesn't silently reintroduce them.
- All money renders in USD regardless of configured currency. The `` token correctly reaches
opportunities.currency, but everyfmtMoneycall site in/crmand/crm/pipelineomits the argument, so the'USD'default renders instead. Affects every non-USD install. Patched locally to GBP. - Next 16 breaks the starter silently. It now defaults
next buildto Turbopack, which OpenNext cannot run on Cloudflare. The build succeeds and the Worker deploys and reports success, then every route 500s with aChunkLoadError. Fixed by pinning--webpackinopen-next.config.ts— don't let this flag get tidied away.