Data flow
How content moves through the system — from a founder's edit in the CMS to an AI agent's tool call.
The two-phase shape
There were two distinct content-lifecycle phases:
- Phase 2 (one-time, archived): the parser ingested
_source/glossary.md+_source/website-copy.mdand produced the canonicaldocs/tree. Then_source/was gitignored. The parser is now archived. - Phase 5+ (ongoing): editors edit
docs/**via the CMS; the build pipeline regenerates AI artifacts on every push.
You're in phase 2. The parser will not run again unless something has gone catastrophically wrong (and even then, only via AOM_FORCE_REPARSE=1 after explicit operator approval).
Editorial flow (CMS → reader)
[Founder]
│
│ visits https://wiki.anatomyofmarketing.dev/admin
│ logs in via GitHub OAuth (sveltia-cms-auth Worker)
▼
[Sveltia CMS]
│
│ reads /admin/config.yml (collections derived from schemas/source.ts via pnpm codegen)
│ editor fills "Examples" / "Common pitfalls" / etc. on a concept
│ Save → CMS uses GitHub API to create a branch + commit
▼
[GitHub: PR opens against main]
│
│ Ne-Lo reviewer reads the diff
│ approves and merges
▼
[GitHub Actions]
│
│ validate.yml — typecheck, test, validate front-matter, schema drift, build
│ axe.yml — a11y gate
│ deploy.yml (Phase 6) — wrangler pages deploy build
▼
[Cloudflare Pages]
│
│ build/ becomes the live site
│ functions/_middleware.ts handles content negotiation per request
▼
[Reader / AI agent]
Build-time pipeline (PR → built artifact)
docs/**/*.md ─┐
schemas/... ─┤
src/css/... ─┤ ┌─────────────────────────┐
src/components ─┼─────►│ pnpm build │
sidebars.ts ─┤ │ (docusaurus build) │
plugins/* ─┤ └────────────┬────────────┘
static/** ─┘ │
├── Docusaurus' classic preset → build/**/*.html
├── theme-mermaid → mermaid SVGs in built HTML
├── search-local → build/search-index-*.json
├── @signalwire/...-llms-txt → build/llms.txt + llms-full.txt + 105 .md mirrors
├── plugins/generate-aom-json → build/aom.json
├── plugins/inject-defined-term → JSON-LD <script> tags injected into 60 concept HTMLs + 6 hat HTMLs
└── static/* copied verbatim → build/admin/, build/courseware/, build/robots.txt
Every artifact is regenerated from the same docs/ tree on every build. There's no out-of-band data store.
AI-agent flow (reader query → answer)
When an MCP-aware client asks a question:
[Claude Desktop / Cursor / ChatGPT]
│
│ user types: "audit Acme's marketing using AoM"
│
▼
[aom-mcp server (local install)]
│
│ on first tool call: fetch https://wiki.anatomyofmarketing.dev/aom.json
│ Zod-validate the payload
│ build BM25 index over concept titles
│ cache in memory for the session
│
│ AI calls list_hats → returns 6 hats
│ AI calls get_hat({slug: "brand-strategy"}) → returns hat metadata + concept slugs
│ AI calls search_concepts({query: "positioning"}) → BM25 ranked match
│ AI calls get_concept({slug: "brand-positioning-statement"}) → full concept
│
▼
[Claude / GPT response cites concept URLs verbatim]
For non-MCP clients, the same data is reachable as:
https://wiki.anatomyofmarketing.dev/aom.json(full graph)https://wiki.anatomyofmarketing.dev/llms.txt(index per llmstxt.org)https://wiki.anatomyofmarketing.dev/llms-full.txt(full spec inlined)https://wiki.anatomyofmarketing.dev/<page>.md(per-page Markdown viaAccept: text/markdowncontent negotiation, OR direct.mdURL)
Reader flow (browser → content)
[User in browser]
│
│ visits https://wiki.anatomyofmarketing.dev/concepts/company-strategy/purpose
│
▼
[Cloudflare edge (Pages)]
│
│ GET request hits functions/_middleware.ts
│ Accept: text/html → fall through to static asset
│ Accept: text/markdown → rewrite to /concepts/company-strategy/purpose.md
│
▼
[Static HTML/Markdown served from Cloudflare's CDN]
│
│ HTML includes:
│ - HatBadge (CSS-only) above the body
│ - 8 schema sections (Definition, Why, How, Framework, In/Out, Examples, Pitfalls, Further reading)
│ - schema.org/DefinedTerm JSON-LD (injected by inject-defined-term)
│ - Open in Claude / ChatGPT / Cite buttons in the footer
│ - Plausible analytics script (no cookies)
▼
[Browser renders + Plausible logs page view]
Where state actually lives
Three places, in order of permanence:
the-kizz/anatomy-of-marketingGitHub repo. Source of truth for content + code. Every edit is a commit.- Cloudflare Pages deployment of that repo. Re-derived from the repo on every push to main. Disposable.
- Plausible analytics aggregates. External; recoverable if needed via Plausible's CSV export.
Nothing else stores state. There is no database, no Redis, no file uploads (courseware bundles will be committed directly to static/courseware/). Killing the Cloudflare account would lose nothing but uptime.