SOPs
Adding a Page to tms-internal
What this wiki is for
Section titled “What this wiki is for”This site is private operational knowledge, auth-gated by Cloudflare Zero Trust. Pages here are for me (and future me) — not for customers, not for the public.
Belongs here:
- SOPs — standard operating procedures I need to pull up mid-task
- Infrastructure reference — machine inventory, credentials map (pointers only, never values), network diagrams
- Project dashboards — running logs and state for multi-session work
- Decision records — why we did something a certain way, so I do not re-litigate it in six months
Does NOT belong here:
- Public-facing content (that goes on themarketingshow.com)
- Customer data or conversations (that lives in GHL, Gmail, etc.)
- Actual secrets — API keys, tokens, passwords. This wiki is a map to secrets, never a vault. Pointers only.
- Ephemeral notes — scratch work, mid-debug state, daily task lists. Those live in the journal or the to-do list.
If a page would be equally useful published publicly, it probably does not belong here.
When to create a new page vs. extend an existing one
Section titled “When to create a new page vs. extend an existing one”Default: extend an existing page.
- New page — the topic is durable, referenced repeatedly, and does not fit cleanly under any existing page’s title.
- Extend existing — the content is a subsection of an existing topic. Add a new H2 or append to the relevant section.
- Rule of thumb: if you would not link to it from another page, it is probably not its own page.
Where pages live
Section titled “Where pages live”Content lives in src/content/docs/ under a section subfolder:
src/content/docs/├── index.mdx # homepage├── agency-model.mdx├── projects.md├── shortcuts.md├── todo.md├── infrastructure/│ ├── overview.md│ ├── machines.md│ ├── vps-services.md│ ├── update-manager.md│ └── claude-code-issues.md├── sops/│ ├── cloudflare-pages-deploy.md│ └── adding-pages-to-tms-internal.md ← you are here└── web-properties/File naming:
- Kebab-case:
update-manager.md, notUpdateManager.mdorupdate_manager.md .mdfor plain markdown,.mdxfor pages that need JSX/components (rare)- The filename becomes the URL slug automatically
Frontmatter template
Section titled “Frontmatter template”Every page starts with this block. Both fields are required.
---title: Short, Specific Titledescription: One sentence. This shows up in link previews and the sidebar tooltip. Write it like a search snippet.---- Title — written like a heading, not like a filename. “Adding a Page to tms-internal” not “adding-pages-tms-internal”.
- Description — one complete sentence. Says what the page is for and who would read it.
Page anatomy
Section titled “Page anatomy”Typical structure for an SOP or reference page:
## What this is (or "Why this exists")1–3 paragraphs. Lead with the purpose: why does this page exist, what problem does it solve?
## [The actual content — multiple H2s]The substance. Checklists, tables, examples, diagrams.
## How to update this pageIf the page needs to change when real-world things change, document the update path here.Example: "When a new Claude Code issue is filed, the /cc-issue skill appends a row to the Open table."
## RelatedLinks to adjacent pages on this wiki or external resources.Not every page needs all four sections. A pure reference page (e.g., machine registry) might skip “How to update this page” if the update path is obvious.
Writing voice
Section titled “Writing voice”Match the rest of the wiki. It reads like me explaining something to myself a month from now.
- Direct. No throat-clearing. Open with the substance —
## The Rule,## The Problem,## How It Works. Never## Why this page existsor## What this isunless the why is genuinely non-obvious from the title and description. - No narrative openings. “So I hit this today,” “Turns out,” “Writing this down so future-me” belongs on themarketingshow.com, not here. Incidents go in a dedicated
## Precedentor## Historysection at the end of the page, never as the opener. - First-person for usage, not story. “I use this when…” and “The CLI owns the same OAuth token as every other local script I run” — good. “So I needed to do X today and…” — fluff.
- No AI-tells. Avoid em-dash triples, “comprehensive,” “leverage,” “seamless,” “delve.” See
~/apps/james-voice/voice-profile.mdfor the full list — but note: thejames-voiceprofile is tuned for blog/YouTube/email. Its warm patterns (“so,” “super,” “right?”) do NOT apply here. Reference prose is plainer. - No contractions in prose intended for voice read-aloud — but for the wiki itself, normal contractions are fine since no one is speaking the page.
- Explain WHY before HOW inside sections. The why is what saves future-me when the how is stale. This does not license a preamble section; weave the why into the first substantive section.
Sidebar registration
Section titled “Sidebar registration”The sidebar is declared explicitly in astro.config.mjs. Some sections use autogenerate (pick up any .md file automatically), others use items (explicit list).
Current config (abbreviated):
sidebar: [ { label: 'Home', slug: 'index' }, { label: 'Infrastructure', items: [ { label: 'Overview', slug: 'infrastructure/overview' }, // ... explicit list, YOU MUST add new pages here ], }, { label: 'SOPs', autogenerate: { directory: 'sops' }, // auto-picks up new files },],If the section uses items, add your new page explicitly. Order matters — pick a spot that groups logically.
If the section uses autogenerate, the new page appears automatically, sorted alphabetically by title. To control order, add a sidebar field in the frontmatter with an order number.
Ship it
Section titled “Ship it”Every page change goes through the normal build + commit + push flow.
- Bump
build.txt:Terminal window echo $(($(cat build.txt) + 1)) > build.txt - Commit with the convention
Build X: short summary:Terminal window git add -A && git commit -m "Build X: add the new page" - Push to the
mainbranch:Terminal window git push - Cloudflare Pages auto-deploys via GitHub Actions within 30 seconds to 2 minutes. The workflow is in
.github/workflows/deploy.yml.
Verify the deploy landed
Section titled “Verify the deploy landed”Cloudflare Access gate makes curl-based verification tricky (it returns 302 to the auth page, not the content). To actually see the page:
bash ~/apps/cc/open-html.sh "https://internal.themarketingshow.com/path/to/page/"Your browser has the Access cookie, so the page will load. If the page is 404, CF Pages has not finished the deploy — wait a minute and try again.
Deprecating a page
Section titled “Deprecating a page”Do not delete. Leave the URL live so old links do not 404.
- Add a
:::cautionadmonition at the top saying the page is stale, with a link to the current source of truth. - Remove the entry from
astro.config.mjsso the page no longer appears in the sidebar. - Commit as
Build X: deprecate {page-name}, redirect readers to {new location}.
Related
Section titled “Related”- Meta-SOP origin: this page was created 2026-04-16 after too many “how did I structure the last one again?” moments.
- Voice reference:
~/apps/james-voice/voice-profile.md - CF Pages deploy SOP: Cloudflare Pages Deploy
- Claude Code Issues log: Claude Code Issues Filed