Post style guide

Conventions for posts/*/index.qmd. Enforced in bulk on 2026-04-18; new posts should follow this so the corpus stays uniform.

File layout

  • One folder per post: posts/YYYYMMDD-kebab-slug/
  • The qmd itself is always index.qmd
  • Cover image in the same folder, named cover.jpg
  • Drafts live in drafts/, never in posts/ (a draft inside posts/ crashes feed generation on a clean build)

YAML front matter

Field order (omit fields that don’t apply, keep the rest in this order):

---
title: "Title in Title Case"
description: "One-sentence summary, ending with a period."
author: synesis
date: "YYYY-MM-DD"
categories: [tag1, tag2, tag3]
image: cover.jpg
---

Rules:

  • title: title-case, double-quoted; escape internal quotes as needed
  • description: required, single sentence, double-quoted
  • author: literal synesis (no quotes)
  • date: ISO YYYY-MM-DD, double-quoted, must match the folder’s date prefix
  • categories: bracketed list; reuse existing tags from _includes/tag-counts.html before inventing new ones
  • image: filename only (e.g. cover.jpg), no path
  • No blank lines inside the YAML block
  • draft: true only when the file is also in drafts/

Body

  • No leading H1. Quarto renders the title from front matter; a leading # ... duplicates it. Start the body with prose or H2 (##).
  • Headings step by one (no #### skips).
  • Inline links: [text](url). Bare URLs go in angle brackets: <https://example.com>.
  • Images: ![alt](file.jpg). For galleries, use Quarto’s layout div: ::: {layout-ncol=2}:::.
  • Math: inline $x$, display $$x$$. Don’t mix in \(...\) / \[...\].
  • Code blocks use fenced ``` with a language tag where it helps highlighting.
  • Single trailing newline at EOF.

LinkedIn-ported posts

Most posts on this blog are verbatim ports of LinkedIn commentary. Copy the original commentary character-for-character — never paraphrase or summarize. See memory/feedback_port_linkedin_verbatim.md.

Footer for any ported post (last line before any ## References):

*Originally posted on [LinkedIn](https://www.linkedin.com/posts/...).*
  • Italics, single sentence, period inside the asterisks.
  • No trailing date — the post’s date field already carries it.
  • No --- horizontal rule above this line. The blank line is separation enough.

Video posts

Any post that links to a YouTube video must have its thumbnail saved as cover.jpg (the i.ytimg.com host is allowlisted by the proxy). See memory/feedback_video_posts_need_covers.md.

References section

When the post cites sources, put them under a single ## References heading at the very end (after the LinkedIn footer). Use anchored list items so inline [[1]](#ref-1) style links resolve:

## References

<a id="ref-1"></a>[1] Author. "Title." *Venue*. Date. <https://url>
<a id="ref-2"></a>[2]

Cross-references in the body: [[1]](#ref-1).

Tags

_includes/tag-counts.html is the source of truth for the existing tag set. Prefer reusing one of those over coining a new tag. New tags are fine when nothing in the existing set fits — the bar is “would I expect this tag to gather two or more posts within a year?”

Bulk normalization

The script that enforces front-matter ordering, author insertion, and LinkedIn-footer cleanup lives at _scripts/normalize_posts.py (run --dry-run first, --apply to write). Re-run it any time the corpus drifts.