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

256 lines
10 KiB
Markdown

# 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:
```bash
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:
```bash
# 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](https://claude.ai/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):**
```rst
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 <URL>`_``
## BLOG POST TAGS
**Check existing tags before writing posts:**
```bash
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 <env> 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 <env>
- 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 <env> first
- **NEVER use** old dates from previous examples or files