russell.ballestrini.net/CLAUDE.md
russell@unturf.com ff956301fe add whitepapers olive branch post, Matrix DevRel cover letter
new post on AGPL vs public domain licensing for three
permacomputer whitepapers. cover letter for Matrix.org
Senior DevRel role. CLAUDE.md updates for Matrix usage
and media gallery link in cover letter template.
2026-03-07 20:06:14 -05:00

13 KiB
Raw Blame History

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: Avoid dashes (em-dashes —, en-dashes , hyphens used as dashes)

  • Do not use em-dashes or en-dashes in any writing (posts, cover letters, documentation)
  • Hyphens only for compound words (e.g., "open-source"), never as sentence punctuation
  • Prefer full stop periods. Split into two sentences instead of connecting with dashes
  • Commas work too, but periods stay preferred
  • Only use a dash if it truly makes more sense than a period or comma

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.

Russell uses & administers Matrix channels on matrix.org. Relevant for DevRel, community, & communication-focused roles.

media.unturf.com - Russell's media gallery (dark theme, black & white aesthetic). Include in cover letter contact links when it strengthens the application (e.g., content/media/DevRel roles).

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>`_ | `Media <https://media.unturf.com>`_

----

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

UNTURF SVG DIAGRAM STYLE GUIDE

All diagrams on russell.ballestrini.net & permacomputer sites follow this style.

Color Palette (dark/light theme compatible)

  • Background: always transparent (never white or black)
  • Node fills: medium-dark saturated colors with fill="white" text
    • Blues: #4a90d9, #1e88e5, #0d47a1, #1a237e
    • Purples: #9370db, #7b68ee, #6c5ce7, #4a148c, #ab47bc
    • Greens: #7cb342, #1b5e20, #00897b
    • Teals: #00acc1, #006064
    • Oranges: #e65100, #e8834a, #ff6f00
    • Reds: #bf360c, #b71c1c, #880e4f
    • Dark neutrals: #2c3e50, #34495e, #546e7a, #616161, #4e342e
  • Gold/yellow nodes (#f9a825, #fdd835): use fill="#1a1a1a" text (NOT #333333)
  • Node strokes: #999999 (never black)
  • Edges/arrows: #aaaaaa stroke & fill
  • Floating text labels: #cccccc (cluster labels, "translates to", etc.)
  • Accent text: #ef5350 (red warnings/claims), #ff6f00 (orange highlights), #66ff66 (green positive)
  • Dashed cluster borders: stroke="#999999" stroke-dasharray="5,2"
  • Plaintext labels (no background): fill="transparent" polygon, text fill="#cccccc"

SVG Dimensions

  • Root SVG: width="100%" height="100%" with viewBox (never fixed pt/px)
  • RST embed: :width: 100% and :align: center

Animation Pattern (CSS only, no JS)

<defs>
<style type="text/css">
@keyframes fadeIn {
  from { opacity: 0; }
  to { opacity: 1; }
}
.anim { opacity: 0; animation: fadeIn 0.8s ease-out forwards; }
.d0 { animation-delay: 0s; }
.d1 { animation-delay: 3s; }
/* ... increment by 2-3s per group */
</style>
</defs>
  • Wrap each conceptual group in <g class="anim dN">
  • Groups fade in sequentially (3s apart for major concepts, 1-2s for chain elements)
  • Keep total animation under 30s

Graphviz Dot Conventions

bgcolor="transparent"
node [fontname="Helvetica" fontsize=12 style="filled,rounded" shape=box color="#999999"]
edge [color="#AAAAAA" arrowsize=0.6 fontcolor="#AAAAAA"]

Post-Processing Checklist

  1. Strip <title> tags: sed -i 's/<title>[^<]*<\/title>//g' (prevents tooltip artifacts)
  2. Replace fixed dimensions: width="100%" height="100%" keeping viewBox
  3. Change cluster label fontcolor from #aaaaaa to #cccccc
  4. Wrap groups with animation classes
  5. Verify: no fill="black", no stroke="black", no fill="#333333"

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
media.unturf.com Media gallery (dark theme, b&w aesthetic)

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