russell.ballestrini.net/CLAUDE.md
russell@unturf.com 6a4cae2a09 add love story about jason (JSON) blog post, writing style rules
new post: semi-bipolar love story about JSON personified as Jason.
swings between euphoria & despair over structured data.

CLAUDE.md: add writing constraints to avoid "the" & verbs "to be"
in blog posts, prefer active verbs & dropped articles.
2026-02-27 12:52:28 -05:00

10 KiB

Claude Memory and Instructions

CRITICAL: ALWAYS CHECK FOR CLAUDE.MD FILES

BEFORE working on ANY repository, ALWAYS check for CLAUDE.md files in this order:

Priority 1: Cross-Repository CLAUDE.md (Global)

  1. Check for global CLAUDE.md: Look for /home/fox/CLAUDE.md or ~/CLAUDE.md
  2. Read & follow global instructions: These apply across ALL repositories on localhost
  3. Global instructions are baseline: These set the foundation for all work

Priority 2: Repository-Specific CLAUDE.md (Local)

  1. Check for repo CLAUDE.md: Use Read to check if ./CLAUDE.md exists in the repository root
  2. Read & follow repo instructions: If found, read the entire CLAUDE.md file & follow all instructions
  3. Repo-specific overrides global: Repository-specific CLAUDE.md instructions override or extend global guidelines
  4. Check README too: Also read README, README.md, or README.rst to understand the project

Priority hierarchy:

  • Repository-specific CLAUDE.md (highest priority)
  • Cross-repository CLAUDE.md (medium priority)
  • This file's instructions (baseline for this specific repo)

Examples of what to look for:

  • Build & test procedures
  • Commit message formats
  • Code style preferences
  • Special workflows or requirements
  • Project-specific constraints
  • Cross-repo conventions & standards

Read README.rst to understand the build system.

you are acting on behalf of russell ballestrini. don't fuck up.

CRITICAL PELICAN TESTING WORKFLOW

BEFORE ANY COMMIT:

  1. ALWAYS test Pelican build: make clean && make html && make formats
  2. Check for build errors: Pelican will fail on RST syntax errors, missing files, etc.
  3. Verify output: make serve and check localhost:8000
  4. NEVER commit without testing the build

PELICAN BUILD PROCESS:

  • Uses Pelican static site generator (Python-based)
  • Converts .rst/.md files to HTML
  • RST syntax errors break the build
  • Missing images/files break the build
  • Invalid slugs/filenames cause issues

PREFERRED BUILD COMMAND:

make clean && make html && make formats

This generates:

  • HTML output from RST/MD sources
  • Markdown versions (index.md) via pandoc
  • Plain text versions (index.txt)
  • JSON Feed (feeds/all.json)
  • JSON Blog (blog.json) with Markdown content
  • AI agent onboarding (llms.txt)

PROPER DEVELOPMENT WORKFLOW:

# Setup virtual environment (once)
make venv

# Test changes before commit (PREFERRED BUILD)
make clean && make html && make formats

# Optional: serve locally to verify
make serve

# Check localhost:8000 for issues
# Only commit if build succeeds
git add specific-files
git commit -m "message"
git push

CRITICAL CONTENT DIRECTORY ISSUE

PROBLEM: Python virtual environments exist in content/uploads/2024/battleship-solvers/env/ and env2/

  • These contain thousands of Python package files (.md, .rst files)
  • Pelican tries to process them as blog content
  • Causes massive build warnings and errors
  • Should NOT be in content directory

SOLUTION NEEDED:

  • Remove env/ and env2/ directories from content/uploads/
  • Add env*/ to .gitignore patterns
  • Keep only actual blog assets in content/uploads/

CRITICAL GIT SAFETY LESSON

DEVASTATING MISTAKE COMMITTED:

I made a catastrophic git error that destroyed user's work in progress:

  1. What I did wrong: Used git add . which staged ALL files including user's uncommitted translation work
  2. The fatal mistake: When trying to fix the staging issue, I used git reset HEAD . which overwrote the working directory files with staged versions
  3. Result: User's uncommitted translation work was completely lost/overwritten

PROPER APPROACH:

  • ALWAYS check git status and git diff first to see what uncommitted work exists
  • NEVER use git add . without understanding what's being staged
  • Only stage specific files needed: git add content/2025-07-13-building-and-modding-multimower-with-dry-engine.rst
  • If I need to unstage, use git restore --staged <file> for specific files, NOT git reset HEAD .

KEY LESSON:

Git operations can be destructive to uncommitted work. Always preserve user's work in progress before any git commands.

This was a serious failure that cost the user their translation work. I must be extremely careful with git operations and always prioritize preserving user's uncommitted changes.

COMMIT MESSAGE POLICY

NEVER add attribution text to commit messages

  • Do not include "🤖 Generated with Claude Code"
  • Do not include "Co-Authored-By: Claude noreply@anthropic.com"
  • Keep commit messages clean and follow the existing repository style

HELPER SCRIPTS AND TEMPORARY FILES

NEVER commit helper scripts or temporary files unless explicitly requested

  • Helper scripts (like append_toc.py, test.py, etc.) are for temporary use only
  • Only commit helper scripts if the user explicitly says to commit them
  • After using a helper script, delete it from the working directory
  • Do not include helper scripts in git commits unless specifically instructed
  • Focus commits on actual content changes, not the tools used to make them

WRITING STYLE

Use "&" instead of "and" most of the time in posts

  • Prefer concise ampersand (&) for connecting words & phrases
  • Example: "disrupt wheels & foster open collaboration" not "disrupt wheels and foster open collaboration"
  • This creates a more casual, punchy writing style that matches the brand voice

Grammar: NEVER use em-dashes (—)

  • Do not use em-dashes in any writing (posts, cover letters, documentation)
  • Instead of em-dashes, prefer splitting into two separate sentences
  • Alternative: use commas or periods for sentence breaks
  • Example to avoid: "The opportunity to work—learning from experienced operators while contributing—combines technical challenge"
  • Correct approach: "The opportunity to work with experienced operators while contributing combines technical challenge." Or split into two sentences: "The opportunity to work combines technical challenge. Learning from experienced operators while contributing enhances the experience."
  • This creates clearer, more direct writing

Grammar: Avoid "the" in posts

  • Never use "the" when "a" works instead
  • Prefer dropping articles entirely when a sentence reads clean without one
  • Example: "angle brackets. closing tags. verbosity." not "the angle brackets. the closing tags. the verbosity."
  • Restructure sentences to eliminate "the" rather than forcing awkward substitutions

Grammar: Avoid verbs "to be" (is, are, was, were, be, been, being)

  • Prefer active verbs over passive or linking constructions
  • Example: "Jason lives everywhere" not "Jason is everywhere"
  • Example: "TOML fits like a studio apartment" not "TOML is a studio apartment"
  • Contractions count: "it's" = "it is", "he's" = "he is", "that's" = "that is"
  • Exception: quoted code output, error messages, & JSON values stay verbatim

JOB SEARCH PREFERENCES

Russell ONLY works remote. Do not apply to or write cover letters for positions that are not fully remote. If a job posting says hybrid, on-site, or in-office, skip it.

JSONRESUME POLICY

NEVER include phone number in JSONResume files - they're public, use email only.

COVER LETTER FORMAT

Location: content/pages/cover-letters/

Naming: YYYY-MM-DD-company-role-russell-ballestrini.rst

Generate PDF: make cover-letters (uses rst2pdf with style file)

RST structure (match resume format):

Russell Ballestrini
===================

.. class:: center

**Role Title | Company Name**

.. class:: center

russell@unturf.com | `russell.ballestrini.net <https://russell.ballestrini.net>`_ | `GitHub <https://github.com/russellballestrini>`_

----

To the [Company] team:

[Body of letter...]

|

Russell Ballestrini

Key formatting rules:

  • Name as RST title (=== underline)
  • Use .. class:: center for role & contact info
  • Horizontal rule (----) separates header from body
  • No Pelican metadata in PDF-only letters (or use RST comments to hide)
  • Use | for vertical spacing before signature
  • Links use RST inline syntax: ```link text `_``

BLOG POST TAGS

Check existing tags before writing posts:

venv/bin/python lib/tag_stats.py       # all tags with counts
venv/bin/python lib/tag_stats.py 5     # only tags with 5+ posts

Core tags (use these):

  • Code, DevOps, Python, Guide, Opinion, Salt, AWS, Project, Docker, Security, Machine Learning, Game Development, Kubernetes

Rules:

  • Always use existing tags when applicable
  • Suggest new tags only if truly needed (new technology/topic area)
  • Tags should be capitalized (e.g., "Python" not "python")
  • Avoid single-use tags; consolidate into broader categories

RUSSELL'S PROJECT TECH STACKS

NEVER assume or guess what language/framework a project uses. Check the actual repo.

Project Stack Description
unsandbox.com Elixir / Phoenix Customer portal (accounts, API keys, billing)
api.unsandbox.com Elixir / Phoenix + Python Code execution API, ZFS containers
un-inception C (primary) + 41 languages CLI client for unsandbox API
uncloseai-speech Python / FastAPI OpenAI-compatible TTS API (Qwen3-TTS)
uncloseai.com JavaScript / Node.js Embeddable AI assistant widget (Hermes 3)
make_post_sell Python / Pyramid E-commerce (Stripe, PayPal, crypto payments)
remarkbox Python / Pyramid Hosted comments service
neopig Python / FastAPI Web archival, crawling, full-text search, dedup
dry C++ / CMake Urho3D fork, 2D/3D game engine

Key corrections for cover letters:

  • unsandbox.com is Elixir/Phoenix, NOT FastAPI or Python
  • uncloseai-speech is Python/FastAPI
  • make_post_sell & remarkbox are Python/Pyramid, NOT Django
  • uncloseai.com is Node.js, NOT Python

DATE HANDLING FOR NEW CONTENT

CRITICAL: ALWAYS check the current date BEFORE creating ANY new documents

  • MANDATORY: Check the section for "Today's date" at the start of EVERY conversation
  • BEFORE creating: Posts, cover letters, blog entries, or any dated content, verify the current date
  • The date may change during long conversations - ALWAYS use the actual current date from
  • File names MUST match the date metadata (e.g., 2025-11-04-post-name.txt with :date: 2025-11-04)
  • When creating new content, use the correct current date in BOTH the filename AND metadata
  • NEVER assume the date - always check first
  • NEVER use old dates from previous examples or files