Agent notes

Pre-commit checklist

Before committing any blog post, always run these checks:

  1. Validate front matter: Ensure title, date, categories, and layout are present and correct.
  2. Check all links: Extract every URL from the post and verify each returns HTTP 200 (or 401 for API endpoints requiring auth). Fix any broken links before committing.
  3. Verify code blocks: Ensure all fenced code blocks have a language tag and that commands are syntactically valid.
  4. Check for secrets: Scan the post for API keys, tokens, or passwords. Never commit secrets to version control.

Commit and push workflow

Visual and navigation changes

Creating a new blog post

Blog posts live in the posts/ directory as Markdown files.

File naming

posts/YYYY-MM-DD-slug.md

The slug should be lowercase, hyphenated, and descriptive (e.g., 2026-04-22-deploy-jupyterhub-openstack-magnum-tofu.md).

YAML front matter (header)

Every post starts with a YAML front matter block. Required and common fields:

---
title: "Your concise post title"
date: YYYY-MM-DD
categories: [category1, category2]
---

Body content and style

Scripts and code

Categories reference

Only use categories that already exist in the blog. To check existing categories, search the categories: field across files in posts/. Never create new categories unless explicitly instructed.

Publishing workflow

  1. Create the new post file in posts/.
  2. Commit and push to the main branch (or open a PR for significant posts).
  3. GitHub Actions renders the Quarto project and publishes to GitHub Pages automatically.
  4. The Netlify build also triggers on pushes to main.

Buffer Social Media

Setup

Channel IDs (organization: 655270181efd918df3d33eff)

PlatformChannel ID
Twitter/X6552702d7a6cf4d23f916d5c
LinkedIn67c6746b3b85969eafee1ee4
Bluesky67c6738e3b85969eafe22a07

Quick post creation

buffer_query() {
  curl -s -X POST "https://api.buffer.com" \
    -H "Authorization: Bearer $BUFFER_KEY" \
    -H "Content-Type: application/json" \
    -d "{\"query\": \"$1\"}"
}

buffer_query "mutation { createPost(input: { text: \"POST TEXT\", channelId: \"CHANNEL_ID\", schedulingType: automatic, mode: addToQueue }) { ... on PostActionSuccess { post { id text dueAt } } ... on MutationError { message } } }"

Workflow for new blog posts

  1. Read the post content
  2. Draft 1 announcement post adapted for each platform (Twitter: short + hashtags, LinkedIn: professional with bullet points, Mastodon/Bluesky: similar to Twitter)
  3. Show drafts to user for approval
  4. Once approved, queue to all 3 channels using Buffer API

Note: If running with Jules, you do not need to do the Buffer social media posting step.