Pre-blog-posting checklist

General tasks applied to every blog post before it goes live. These steps are independent of the blog content.

Site context: This is hackgptdeveloper.github.io — a tech/security/AI blog using the mmistakes/so-simple-theme Jekyll remote theme. Posts cover security exploitation, AI/LLM agents, web technologies, and related topics. The site uses tags: in frontmatter (not categories:). Math/LaTeX rules in this checklist apply only to posts containing mathematical notation; skip sections 5 and 12 for non-math posts.


0. Writing style: direct English

Apply these rules when writing, editing, or combining content. They take priority over any instruction that encourages hype, decorative phrasing, or unnecessary length.

  • Preserve all technical content. Do not remove technical details, derivations, assumptions, limitations, examples, code, references, or explanations to make the prose shorter.
  • Use direct, clear English. Express simple ideas simply. Use technical terms when they are needed for accuracy, and explain unfamiliar terms where they first appear.
  • Remove non-essential exaggeration, filler, repetition, promotional language, and dramatic framing. Do not add special phrasing just to make technical content sound important.
  • State what happens, how it works, and why it matters in concrete terms. Replace vague praise with the specific mechanism, result, or limitation.
  • Prefer ordinary verbs and short, readable sentences. Split sentences when that improves clarity; do not impose a word limit or remove necessary reasoning.
  • Avoid stock introductions and transitions such as “let us embark on,” “dive into,” “unlock the secrets,” “a fascinating journey,” and “it is important to note.” Start with the actual point.
  • Avoid unsupported labels such as “groundbreaking,” “revolutionary,” “game-changing,” “mind-blowing,” “remarkable,” or “powerful.” If a claim of significance is necessary, explain and support it.
  • Keep qualifications that affect correctness. Do not turn a conditional result into an absolute claim to make it sound stronger.
  • Use neutral, descriptive titles and headings. Do not use clickbait, artificial suspense, or claims of secrecy, beauty, or surprise merely to attract attention.
  • Use emphasis to identify useful information, not to manufacture excitement.
  • Add SVG diagrams when they help explain memory corruption or another complex concept. Label relevant addresses, offsets, objects, states, and transitions accurately. Place each diagram beside the explanation it supports; do not add decorative diagrams.

Examples of the intended style:

Avoid Use
“Let us dive into the fascinating world of type confusion.” “Type confusion occurs when a value is used as the wrong type.”
“This powerful technique unlocks arbitrary memory access.” “Under these conditions, this technique allows arbitrary memory access.”
“The real magic happens in the next step.” “The next step overwrites the object’s length field.”
“This elegant formula reveals a profound connection.” “This formula relates X to Y.”
“It is important to note that the exploit requires this version.” “The exploit requires this version.”

Before accepting a rewrite, check both technical completeness and language. Remove unnecessary words, not necessary explanations.


1. Source material preparation

Read the raw content file and identify:

  • The core theorem/identity/concept
  • Natural connections to other topics (cross-linking opportunities)
  • Whether the post contains LaTeX math (if yes → sections 5 and 12 apply; if no → skip them entirely)
  • Sections that need markdown formatting removed from math blocks
  • Any raw < or > characters in math that need LaTeX replacement
  • Whether an illustration file exists to integrate (e.g. *_illustration.md) — merge its diagrams inline

2. Frontmatter

Every post must have this YAML block at the top:

---
title: "..."
tags:
  - tag-one
  - tag-two
---

Rules (specific to this blog — hackgptdeveloper.github.io):

  • date: derived from the filename (YYYY-MM-DD-slug.md), NOT placed in frontmatter
  • tags:: kebab-case, narrowly topical, 4-8 of them. This blog uses tags: only — do NOT add categories:, excerpt:, share:, or read_time: to frontmatter (the theme auto-generates excerpts and the config does not enable these frontmatter keys)
  • No Mathematics category — this is a tech/security/AI blog, not a math blog
  • The filename format is YYYY-MM-DD-slug.md inside _posts/

3. Title requirements

Use a clear, specific title that identifies the subject and the main result, mechanism, or question.

Rules:

  • Describe what the post actually explains.
  • Name the relevant technology, vulnerability, theorem, or method when useful.
  • Keep the title as short as accuracy allows.
  • Do not promise a revelation, exaggerate the result, or imply secrecy or novelty without evidence.
  • Do not require a “viral-style” title. A straightforward title is acceptable.

Examples:

  • “How Type Confusion Leads to an Out-of-Bounds Read”
  • “Configuring OIDC Authentication for a Multi-Tenant API”
  • “Deriving the Hexagon Spiral Formula”

4. Opening challenge

Immediately after the frontmatter, place a challenge to the reader in bold:

**Challenge to the reader:** [concrete, verifiable task using the post's content]

Rules:

  • It must be specific (e.g. “Compute X for Y” not “Explore X”)
  • It must be solvable after reading the post
  • It appears before any body text
  • Use direct wording. Do not frame it as a teaser or exaggerate its difficulty or significance.

Scatter 2-3 additional challenges at midpoints and one final challenge at the end.


5. Math rendering rules

⚠️ Conditional: skip this entire section if the post contains no LaTeX math. For non-math posts (security exploits, AI/LLM, web tech), none of these rules apply.

5a. Site-level prerequisite (checked once, not per post)

Math rendering depends on the MathJax configuration in _includes/scripts.html. It must declare the $/$$ delimiters in the MathJax.tex config:

MathJax = {
  tex: {
    tags: "ams",
    inlineMath: [['$', '$'], ['\\(', '\\)']],
    displayMath: [['$$', '$$'], ['\\[', '\\]']]
  }
}

Why this is required — GitHub Pages builds with kramdown 2.5.x, which:

  • Converts $$...$$ display blocks into \[...\] blocks in the HTML (this is normal — MathJax renders them via the displayMath config above)
  • Leaves $...$ inline math as literal text in the HTML (rendered only because inlineMath declares $)

Never add an options.renderActions.find override to this config. Overriding find replaces MathJax’s default finder and disables ALL math rendering site-wide (inline $...$ and \[...\] blocks). This was the bug that broke the hexagon-spiral posts.

Applied to every math-containing post:

Rule Do Don’t
Display math $$...$$ \[...\], \\[...\\]
Inline math $...$ \(...\)
Inside math Valid LaTeX only No ====, ---, *, markdown links
Inequalities $\lvert z \rvert < 1$ Raw |z|<1 outside math
Curly braces {}_2F_1, \frac{a}{b} — safe N/A

Long equations use alignment environments:

$$
\begin{aligned}
x &= a + b \\
y &= c + d
\end{aligned}
$$

6. Content structure

Every post follows this skeleton:

  1. Challenge (bold, before any body text)
  2. Core concept/theorem stated upfront
  3. Practical use or consequence (2-3 lines explaining a concrete use, effect, or limitation)
  4. Numbered sections — each section is one digestible idea
  5. Mid-post challenges (after key derivations)
  6. Reference table (where applicable — show related functions, offset maps, comparison matrices)
  7. Mechanism / root cause / implications section, as appropriate; explain the actual relationship rather than adding a generic significance paragraph
  8. Final challenge (harder, synthesis-required)
  9. Source code / references (where applicable — link to repos, CVEs, further reading)

Section headings use ## N. Descriptive Name format. Name the mechanism or topic directly; avoid dramatic or promotional headings.

For non-math posts (security, AI, web tech), replace “core theorem” with the post’s central concept or finding, and “connection table” with any structured reference (offset map, comparison table, exploit summary table, etc.).


7. Visual separators

Use --- to separate major sections. These must be on their own line, outside any $$...$$ blocks.


8. Pre-publish verification

Language and technical-content review — every post

  • Compare the draft with the source material. Confirm that no technical content was lost while rewriting or combining files.
  • Check the title, headings, introduction, transitions, challenges, diagram labels, and conclusion against section 0.
  • Remove exaggeration, filler, repeated summaries, and unnecessary adjectives. Keep definitions, reasoning, evidence, caveats, and useful examples.
  • Replace vague claims of importance with a specific explanation, or remove the claim if it adds nothing.
  • Confirm that SVG diagrams clarify the explanation and agree with the text and code.

Rendering checks

⚠️ Conditional: Checks 1, 4, 5, and the pipe/math sub-checks apply only to posts with LaTeX math. For non-math posts, only run checks 2 and 3 (and even then, only to confirm no accidental </> issues).

Run these commands in the repo root, replacing the filename:

# 1. [MATH ONLY] No old-style math delimiters (should print nothing)
grep -n '\\\\\[\|\\\\\]\|\\(' _posts/NEW-FILE.md

# 2. No markdown headings/rules inside math blocks (should print nothing;
#    lines matching "---" or "====" are only legitimate section separators
#    OUTSIDE $$...$$ blocks)
grep -n '^=\|^--' _posts/NEW-FILE.md

# 3. No raw < or > outside of valid HTML tags and math mode
grep -n '<\|>' _posts/NEW-FILE.md

For check 2 and 3, manually verify that any matches are:

  • Frontmatter --- delimiters (legitimate)
  • Section separator --- lines (legitimate)
  • HTML tags like </script> (legitimate)
  • LaTeX commands like \lt, \gt, \langle (legitimate in $$/$)
  • Code arrows like ->, => (legitimate in code blocks and text)
  • Markdown table pipes | (legitimate outside math mode)

For check 2, also scan for | (pipe) inside inline $...$ math on the same line — kramdown interprets pipes as table column separators, shattering inline math into broken HTML table cells. Pattern: $...|...$ → use \lvert/\rvert instead:

# [MATH ONLY]
grep -n '\$.*|.*\$' _posts/NEW-FILE.md

9. Git workflow

# Stage the new post
git add _posts/NEW-FILE.md

# Commit with a message that summarizes the post content
git commit -m "Add [topic] blog post

[One line describing the core content]

Co-Authored-By: Claude <noreply@anthropic.com>"

# Push to deploy (GitHub Pages rebuilds automatically)
git push

Never amend. Always create a new commit. Never skip hooks.


10. Post-publish verification

After pushing, wait ~2 minutes for GitHub Pages to rebuild, then:

  1. Visit the live URL: https://hackgptdeveloper.github.io/YYYY/MM/DD/slug.html (note: URL format is date-based, not category-based)
  2. [MATH ONLY] Check that all $$ blocks render as math, not raw LaTeX
  3. [MATH ONLY] Check that inline $ renders correctly
  4. Verify the title, tags appear on the listing page
  5. Verify the site index at https://hackgptdeveloper.github.io/ lists the new post
  6. Verify updated content — if you edited the post after pushing, curl the page and grep for key strings to confirm the latest commit rendered (e.g. curl -s <url> | grep -c "expected-string")

If math shows as raw LaTeX on the live page, diagnose in this order:

Symptom Cause Fix
Inline $...$ shows as raw text on EVERY math post _includes/scripts.html is missing the inlineMath/displayMath delimiter config (see section 5a) Restore the MathJax.tex config shown in 5a
NO math renders anywhere (inline or display) An options.renderActions.find override was added to _includes/scripts.html — it replaces MathJax’s default finder Remove the renderActions block entirely
Only display $$...$$ blocks show raw Check the source for markdown inside the block, or a ---/table row interfering with the $$ block Re-run the grep checks from section 8
Single math span broken, others fine kramdown escape pitfalls inside $...$ — \#/\{/\} stripped, \\ collapsed, or | shattering a table Fix per section 12

Notes:

  • Seeing \[...\] in the rendered HTML source is EXPECTED (kramdown converts $$...$$ to it) and is not a problem — MathJax renders it client-side
  • Raw $...$ visible on the page is the failure signal, not raw \[

11. Post-publish: homepage and build verification

After the blog posts are deployed, always verify the homepage and site health.

11a. Homepage must show new posts

Visit https://hackgptdeveloper.github.io/ and confirm the new posts appear. If they don’t:

Symptom Likely cause Fix
Latest posts missing from homepage Posts have future dates relative to build time (Jekyll excludes future-dated posts by default) Add future: true to _config.yml
Homepage shows wrong layout Wrong index file is active Ensure index.html (not index.md) is committed — .html wins when both exist, and jekyll-paginate requires .html
Pagination broken / only some posts show paginate: false set in index, or index.md overriding index.html Use index.html with paginate: true; delete index.md to avoid conflicts
Stale content after push One of the dual workflows was cancelled; or the deploy workflow didn’t finish Check both workflow runs at GitHub Actions tab; re-trigger if needed

11b. Verify index file state

The site requires index.html at the root (not index.md) because the jekyll-paginate plugin generates numbered pages from it. Run:

# Check which index files are tracked
git ls-files index.html index.md

# Check for untracked index files
git status -- index.html index.md

Expected: index.html is tracked, index.md is NOT tracked.

11c. Verify site config for future posts

# config must include future: true to show posts dated ahead of build time
grep 'future:' _config.yml

Note: This blog’s _config.yml does NOT currently have future: true. Posts dated today or earlier appear without it. If you ever publish a post with a future date (e.g. scheduling ahead), add future: true under the # Site settings line — otherwise Jekyll silently excludes it from the build.

11d. Check both GitHub Actions workflows

The repo has two deploy workflows (.github/workflows/jekyll.yml and jekyll-gh-pages.yml). Both trigger on push to main. At least one must complete with success for the site to update. Check:

https://github.com/hackgptdeveloper/hackgptdeveloper.github.io/actions

If the latest run of either workflow shows cancelled, the deployment may still be fine if the other workflow succeeded — but verify the live site. If both failed/cancelled, push an empty commit to re-trigger:

git commit --allow-empty -m "Re-trigger build"
git push

11e. Verify individual post pages

Pick 2-3 new post URLs from the homepage and curl them to confirm HTTP 200:

curl -sI https://hackgptdeveloper.github.io/YYYY/MM/DD/slug.html | head -3

A 404 on a new post usually means the post was excluded at build time (future date — see 11a).

11f. Homepage layout requirements

The homepage (index.html) should have:

---
layout: home
show_excerpts: true
paginate: true
entries_layout: grid   # 3-column grid; use 'list' for single-column
---

The 3-column grid is configured in _includes/head-custom.html. If the grid breaks, check that file for the .entries-grid CSS override and the .layout--home.page--wide .page-wrapper width setting (default: 1400px).


Quick reference card

□ Frontmatter: title + tags: only (no categories/excerpt/share/read_time)
□ Date in filename: YYYY-MM-DD-slug.md
□ Direct English throughout: no hype, filler, or decorative phrasing
□ Technical content preserved when editing or combining sources
□ Clear, specific title and descriptive headings; no clickbait
□ Concrete mechanisms, results, and limitations instead of vague praise
□ SVG diagrams included where they clarify memory corruption or other complex concepts
□ Reader challenge at top (bold, concrete)
□ [MATH ONLY] All math uses $$ / $ delimiters
□ [MATH ONLY] Site config intact: _includes/scripts.html declares $/$$ delimiters and has NO renderActions.find override (section 5a)
□ [MATH ONLY] No markdown inside $$ blocks
□ [MATH ONLY] No raw < > in math mode
□ [MATH ONLY] No \#, \{, \} in inline $...$ math (use \lbrace, \rbrace, \lvert, \rvert)
□ [MATH ONLY] No | (pipe) in inline $...$ math (use \lvert, \rvert)
□ [MATH ONLY] Inline matrices: \\ doubled to \\\\ (only inside $...$, not $$...$$)
□ [MATH ONLY] Prefer display math $$...$$ for matrices (keeps \\ as-is)
□ 2-3 additional challenges scattered through post
□ Final challenge at end
□ Source code / reference links at bottom (if applicable)
□ Illustration files merged inline (if *_illustration.md exists)
□ grep checks pass (run math checks only for math posts; always run checks 2+3)
□ git commit + push
□ Live URL: https://hackgptdeveloper.github.io/YYYY/MM/DD/slug.html verified HTTP 200
□ Homepage shows new posts (https://hackgptdeveloper.github.io/)
□ Both GitHub Actions workflows succeeded (or at least one)
□ index.html tracked, index.md removed
□ Individual post pages return HTTP 200

12. kramdown escaping pitfalls in math mode

⚠️ Conditional: skip this entire section if the post contains no LaTeX math. These issues only affect $...$ inline math spans.

kramdown (Jekyll’s markdown processor) treats certain backslash-character combinations as markdown escapes, even inside $...$ inline math spans. This silently corrupts LaTeX before it reaches MathJax. Display math $$...$$ blocks are not affected.

12a. The \#, \{, \} problem

kramdown interprets \#, \{, \} as escaped markdown special characters and strips the backslash, producing bare #, {, } in the HTML output:

Source kramdown output MathJax sees Result
\# # # Error: “macro parameter character # in math mode”
\{ { { Invisible grouping brace — set notation vanishes
\} } } Invisible grouping brace — set notation vanishes

Fix: Use letter-based LaTeX commands instead. kramdown only strips backslashes before markdown special characters — backslash-letter sequences pass through unchanged:

Bad (markdown special char) Good (letter-based command)
\# (cardinality) \lvert ... \rvert for bars, or \# cannot be used
\{ (left brace) \lbrace
\} (right brace) \rbrace
\#{i : b_i = 1} \lvert\lbrace i : b_i = 1\rbrace\rvert

12b. The \\ line-break problem in inline matrices

kramdown processes \\ inside inline $...$ math as an escaped backslash, consuming one \ and leaving \ — which MathJax treats as a control space instead of a line break. This causes pmatrix, bmatrix, and other matrix environments to render as a single horizontal row.

Source kramdown output MathJax sees Result
\begin{pmatrix} a & b \\ c & d \end{pmatrix} \begin{pmatrix} a & b \ c & d \end{pmatrix} Control space \ Matrix renders as one row

Fix: Double \\ to \\\\ in inline math only. kramdown processes \\\\ as two escaped backslashes → \\, which MathJax correctly interprets as a line break:

<!-- WRONG — renders as single row -->
$\begin{pmatrix} a & b \\ c & d \end{pmatrix}$

<!-- CORRECT — \\\\ becomes \\ after kramdown -->
$\begin{pmatrix} a & b \\\\ c & d \end{pmatrix}$

Display math $$...$$ does NOT need this fix — \\ passes through unchanged.

12c. Pre-publish grep for these issues

Add these checks to the section 8 verification:

# 4. Inline matrices with single \\ (should print nothing — or verify
#    matches are only inside $$...$$ display math blocks)
grep -n '\$.*\\\\begin{pmatrix}.*[^\\]\\\\[^\\].*\\\\end{pmatrix}' _posts/NEW-FILE.md

# 5. \#, \{, or \} inside inline math (should print nothing)
grep -n '\$.*\\[#{}]' _posts/NEW-FILE.md

For check 4, if output appears, verify each match is inside a $$...$$ block — not inside $...$. For check 5, all matches must be replaced with letter-based commands.

12d. Quick decision tree

When writing math in a blog post:

Is the LaTeX inside $...$ (inline) or $$...$$ (display)?
  ├─ $$...$$ (display): write LaTeX normally, no special escaping
  └─ $...$ (inline):
       ├─ Contains \begin{pmatrix} / \begin{bmatrix} / etc.?
       │    └─ YES → double all \\ to \\\\
       ├─ Contains \# (hash)?
       │    └─ YES → replace with \lvert...\rvert or rewrite
       ├─ Contains \{ or \} (set braces)?
       │    └─ YES → replace with \lbrace and \rbrace
       ├─ Contains | (pipe)?
       │    └─ YES → replace with \lvert and \rvert
       └─ None of the above → write normally

12e. The | (pipe) problem — kramdown table parsing

kramdown interprets | characters as markdown table column separators, even inside $...$ inline math. This shatters the math into broken HTML <table> cells:

Source (single line) kramdown output
The set $\lbrace z : \|z\| \ge 1\rbrace$ is... <td>The set $\lbrace z :</td><td>z</td><td>\ge 1\rbrace$ is...</td>

A single | inside $...$ on a line with two or more pipes triggers table parsing. The math gets split across <td> cells and becomes unrenderable.

Fix: Replace | inside inline math with \lvert and \rvert:

<!-- WRONG — pipes trigger table parsing -->
The set $\lbrace z : |z| \ge 1\rbrace$ is a fundamental domain

<!-- CORRECT — \lvert/\rvert are letter-based, safe from kramdown -->
The set $\lbrace z : \lvert z\rvert \ge 1\rbrace$ is a fundamental domain

12f. Preferred alternative: move matrices to display math

When a matrix is complex or contains multiple rows, prefer $$...$$ display math. It avoids the escaping problem entirely and is more readable:

<!-- Instead of inline: -->
The matrix $M = \begin{pmatrix} a & b \\\\ c & d \end{pmatrix}$ has ...

<!-- Use display math: -->
The matrix

$$
M = \begin{pmatrix} a & b \\ c & d \end{pmatrix}
$$

has ...

13. Blog-specific conventions (hackgptdeveloper.github.io)

The direct-English rules in section 0 apply to all posts, including technical explanations, challenges, captions, and source-code introductions.

These were discovered during the type-confusion exploit walkthrough posting and differ from the generic math-blog template this checklist was originally written for.

13a. Frontmatter — tags only

This blog uses tags: exclusively. Do NOT add categories:, excerpt:, share:, or read_time: to frontmatter. The so-simple theme auto-generates excerpts from the post body, and the config doesn’t enable these frontmatter keys. The date is derived from the filename.

13b. URL scheme

Post URLs follow the pattern /YYYY/MM/DD/slug.html — not /category/.../. This is Jekyll’s default permalink behavior with the so-simple theme.

13c. Math is conditional

This is a tech/security/AI blog, not a mathematics blog. Many posts contain zero LaTeX. The math rendering rules (sections 5, 12) and math-specific grep checks (section 8 checks 1, 4, 5, pipe check) apply only when the post actually contains $...$ or $$...$$. For non-math posts (security exploits, AI agents, web technologies), skip those sections entirely.

13d. future: not set in config

_config.yml does not have future: true. This is fine for same-day or past-dated posts. If you ever schedule a post with a future date, add it.

13e. Integration of illustration files

When a companion *_illustration.md file exists alongside the main content, merge its diagrams and tables inline into the post rather than keeping them as separate files. This was done for type_confusion_illustration.md → integrated into the Phase 2 and Phase 3 sections.

13f. Source code references

For posts that reference a working exploit, demo, or codebase, add a “Source Code” section at the bottom with a direct link to the GitHub repo. This gives readers a concrete artifact to study alongside the writeup.

13g. Post-publish content verification

When edits are made after the initial push, don’t just check HTTP 200 — grep the rendered HTML for key strings to confirm the latest commit’s content actually deployed. Example:

curl -s https://hackgptdeveloper.github.io/YYYY/MM/DD/slug.html | grep -c "expected-string"