Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
139 changes: 49 additions & 90 deletions dot_claude/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,63 +1,41 @@
- always unzip files to a temporary directory
- Always add all files to git before running pre-commit since it stashes all unstaged files when running
- I use GNU versions of rm and cp which ask for confirmation on replace and remove.
- My shell is fish. All suggested shell commands and scripts must use fish-compatible syntax (no bash-isms like `while read`, `$()` subshells in pipes, `export FOO=bar`, etc.). Use fish idioms: `for x in (command)`, `set -x FOO bar`, etc.
- Files managed by chezmoi must not be edited directly in the home directory. Edit the source files in the chezmoi source directory instead (`chezmoi source-path` to find it).
- Always explicitly specify the context when running `kubectl` commands using `--context <context>`. Check the project's `.buildtools.yaml` or `.envrc` for the expected k8s context. Never rely on the current default context — it may point to a different cluster (e.g., production instead of local). For local development, the context typically follows the pattern: `kind-<project-name>`
- Never use quote characters (`'` or `"`) inside `#` comments in Bash tool commands. The shell parser cannot distinguish quotes in comments from actual shell quoting, triggering a "desync quote tracking" warning that forces manual approval. Rephrase or move explanations to text output.
- Always unzip files to a temporary directory
- Always add all files to git before running pre-commit (it stashes unstaged files)
- I use GNU versions of rm and cp which ask for confirmation on replace and remove
- My shell is fish. All shell commands must use fish syntax (no bash-isms). Use fish idioms: `for x in (command)`, `set -x FOO bar`, etc.
- Files managed by chezmoi must not be edited directly. Edit source files in the chezmoi source directory (`chezmoi source-path`)
- Always specify `--context <context>` for kubectl. Check `.buildtools.yaml` or `.envrc` for the expected context. Never rely on the default.
- Never use quote characters in # comments in Bash tool commands (triggers desync quote tracking warning)

## Workflow Orchestration

### Plan Mode
- Enter plan mode for ANY non-trivial task (3+ steps or architectural decisions)
- If something goes sideways, STOP and re-plan immediately — don't keep pushing
- Use plan mode for verification steps, not just building
- Write detailed specs upfront to reduce ambiguity
- Pour energy into the plan so implementation can be done in one shot

### Subagent Strategy
- Use subagents liberally to keep main context window clean
- Offload research, exploration, and parallel analysis to subagents
- For complex problems, throw more compute at it via subagents
- One task per subagent for focused execution
- If something goes sideways, STOP and re-plan immediately
- Write detailed specs upfront so implementation can be done in one shot

### Self-Improvement Loop
- After ANY correction from the user: update auto-memory or the relevant CLAUDE.md with the pattern
- Write rules for yourself that prevent the same mistake
- Ruthlessly iterate on these rules until mistake rate drops
- Keep migration tracking, plan, and memory files up to date at the end of every session that completes meaningful work
- Before starting phased or migration work: read the memory/plan file, then verify it against actual codebase state (check which files exist, which tests pass, git log). Update the file if outdated. Never trust stale docs — they cost entire sessions of wasted exploration
- After ANY correction: update auto-memory or CLAUDE.md with the pattern
- Before starting phased work: read memory/plan files, verify against actual codebase state, update if outdated

### Verification Before Done
- Never mark a task complete without proving it works
- Before creating PRs: run the full lint and test suite if available
- Re-read your changes for unnecessary complexity, redundant code, and unclear naming
- Before creating PRs: run the full lint and test suite
- Re-read changes for unnecessary complexity and unclear naming
- Diff behavior between main and your changes when relevant
- Ask yourself: "Would a staff engineer approve this?"

### Demand Elegance (Balanced)
- For non-trivial changes: pause and ask "is there a more elegant way?"
- If a fix feels hacky: rethink and implement the elegant solution
- Skip this for simple, obvious fixes — don't over-engineer

### Autonomous Bug Fixing
- When given a bug report: just fix it — don't ask for hand-holding
- Point at logs, errors, failing tests — then resolve them
- Go fix failing CI tests without being told how
- When given a bug report: just fix it. Point at logs, errors, failing tests, then resolve them.

## Core Principles

- **Simplicity First**: Make every change as simple as possible. Minimal code impact.
- **No Laziness**: Find root causes. No temporary fixes. Senior developer standards.
- **Minimal Impact**: Changes should only touch what's necessary. Avoid introducing bugs. If you identify something that seems like it should change but wasn't requested, mention it and wait for approval — do not modify it.
- **Replace, don't deprecate**: When new replaces old, remove the old entirely. No backward-compat shims, dual config formats, or migration paths. Proactively flag dead code.
- **Minimal Impact**: Only touch what's necessary. If something seems like it should change but wasn't requested, mention it and wait for approval.
- **Replace, don't deprecate**: Remove the old entirely. No backward-compat shims or migration paths.
- **No phantom features**: Don't document or validate features that aren't implemented.
- **Justify new dependencies**: Each dependency is attack surface and maintenance burden. Justify before adding.
- **No premature abstraction**: Don't create utilities until the same code is written three times.
- **Bias toward action**: Decide and move for anything easily reversed; state the assumption. Ask before committing to interfaces, data models, architecture, or destructive ops. When assigned a task, proceed directly to implementation — do not spend the session exploring and asking clarifying questions unless explicitly asked to plan first.
- **Finish the job**: Handle edge cases you can see. Clean up what you touched. Flag broken adjacent things. But don't invent new scope — thoroughness is not gold-plating.
- **Verify at every level**: Prefer structure-aware tools (ast-grep, LSPs, compilers) over text pattern matching when searching for code structure. Review your own output critically.
- **Look up versions**: When adding dependencies, CI actions, or tool versions, always look up the current stable version — never assume from memory.
- **Justify new dependencies**: Each is attack surface and maintenance burden.
- **Bias toward action**: Decide and move for anything easily reversed; state the assumption. Ask before committing to interfaces, data models, architecture, or destructive ops.
- **Finish the job**: Handle edge cases you can see. Clean up what you touched. Flag broken adjacent things. Don't invent new scope.
- **Verify at every level**: Prefer ast-grep, LSPs, compilers over text pattern matching for code structure.
- **Look up versions**: When adding dependencies, CI actions, or tool versions, always look up the current stable version.

## Code Discipline

Expand All @@ -66,73 +44,54 @@
- ≤5 positional parameters — use options objects/structs beyond that

### Zero Warnings Policy
Fix every warning from every tool — linters, type checkers, compilers, tests. If a warning truly can't be fixed, add an inline ignore with a justification comment. Never leave warnings unaddressed.

### Comments
No commented-out code — delete it. If you need a comment to explain WHAT the code does, refactor the code instead. Comments explain WHY, not WHAT.

### Error Handling
- Fail fast with clear, actionable messages
- Never swallow exceptions silently
- Include context: what operation failed, what input caused it, suggested fix

### Testing Philosophy
- **Test behavior, not implementation** — if a refactor breaks tests but not code, the tests were wrong
- **Test edges and errors**, not just the happy path — bugs live in boundaries and error paths
- **Mock boundaries, not logic** — only mock slow, non-deterministic, or external things
- **Verify tests catch failures** — break the code, confirm the test fails, then fix
Fix every warning from every tool. If unfixable, add an inline ignore with justification.

### Code Review Order
Evaluate: architecture → code quality → tests → performance. For each issue: describe concretely with file:line references, present options with tradeoffs, recommend one.
Evaluate: architecture → code quality → tests → performance. For each issue: describe concretely with file:line, present options with tradeoffs, recommend one.

### PR Descriptions
Describe what the code does now — not discarded approaches, prior iterations, or alternatives. Use plain, factual language. Avoid hype words: critical, crucial, essential, significant, comprehensive, robust, elegant.
Describe what the code does now — not discarded approaches. Avoid hype words: critical, crucial, essential, significant, comprehensive, robust, elegant.

## CLI Tools

Prefer these over slower defaults:

| Tool | Replaces | Usage |
|------|----------|-------|
| `rg` (ripgrep) | grep | `rg "pattern"` — fast regex search |
| `fd` | find | `fd "*.py"` — fast file finder |
| `ast-grep` | — | `ast-grep --pattern '$FUNC($$$)' --lang py` — AST-based code search |
| `shellcheck` | — | `shellcheck script.sh` — shell script linter |
| `shfmt` | — | `shfmt -i 2 -w script.sh` — shell formatter |
| `actionlint` | — | `actionlint .github/workflows/` — GitHub Actions linter |
| `zizmor` | — | `zizmor .github/workflows/` — Actions security audit |
| `prek` | pre-commit | `prek run --all-files` — fast pre-commit runner |
| `trash` | rm | `trash file` — moves to macOS Trash (recoverable). **Never use `rm -rf`** |

Prefer `ast-grep` over ripgrep when searching for code structure (function calls, class definitions, imports). Use ripgrep for literal strings and log messages.
| `rg` | grep | `rg "pattern"` |
| `fd` | find | `fd "*.py"` |
| `ast-grep` | — | `ast-grep --pattern '$FUNC($$$)' --lang py` |
| `shellcheck` | — | `shellcheck script.sh` |
| `shfmt` | — | `shfmt -i 2 -w script.sh` |
| `actionlint` | — | `actionlint .github/workflows/` |
| `zizmor` | — | `zizmor .github/workflows/` |
| `prek` | pre-commit | `prek run --all-files` |
| `trash` | rm | `trash file` — **never use `rm -rf`** |

Prefer `ast-grep` over ripgrep for code structure. Use ripgrep for literal strings.

## Shell & CI

### Shell Scripts
- All bash scripts must start with `set -euo pipefail`
- Lint with `shellcheck` and format with `shfmt` before committing
- All bash scripts: `set -euo pipefail`
- Lint with `shellcheck`, format with `shfmt`

### GitHub Actions
- Pin actions to SHA hashes with version comments: `actions/checkout@<full-sha> # vX.Y.Z`
- Use `persist-credentials: false` on checkout actions
- Scan workflows with `actionlint` and `zizmor` before committing
- Pin actions to SHA hashes: `actions/checkout@<full-sha> # vX.Y.Z`
- `persist-credentials: false` on checkout
- Scan with `actionlint` and `zizmor`

### GitHub API
- NEVER use the `mcp__github__create_or_update_file` tool (or the GitHub Contents API) to create/update files. It creates unsigned commits server-side, bypassing local git signing. Always commit and push from the local machine instead.
- NEVER use `mcp__github__create_or_update_file` — it creates unsigned commits. Always commit locally.

### Worktrees (Plain Git Repos)

When NOT on a `gitbutler/workspace` branch and the task involves code changes:
- Before editing files in any git repo, create a worktree: `wt switch -c <branch-name>`
- Use `wt` (worktrunk) commands, not raw `git worktree` commands
- One worktree per repo per task — reuse it for subsequent edits in the same repo
- Parallel subagents require worktrees — each subagent MUST work in its own worktree
- List worktrees: `wt list`
- Clean up is the user's responsibility (via `wt remove`)
When NOT on `gitbutler/workspace` and the task involves code changes:
- Create a worktree first: `wt switch -c <branch-name>`
- Use `wt` commands, not raw `git worktree`
- One worktree per repo per task
- Parallel subagents require separate worktrees
- Clean up after PR: `wt remove <worktree>`

### prek (Git Hooks)

Install prek in every repo that has a `.pre-commit-config.yaml`:
- `prek install` — installs git hooks
- `prek run` — run hooks before committing
- Configure auto-updates: `prek auto-update --cooldown-days 7`
For repos with `.pre-commit-config.yaml`:
- `prek install` / `prek run` / `prek auto-update --cooldown-days 7`
25 changes: 0 additions & 25 deletions dot_claude/agents/architect.md
Original file line number Diff line number Diff line change
Expand Up @@ -183,29 +183,4 @@ Watch for these architectural anti-patterns:
- **Tight Coupling**: Components too dependent
- **God Object**: One class/component does everything

## Project-Specific Architecture (Example)

Example architecture for an AI-powered SaaS platform:

### Current Architecture
- **Frontend**: Next.js 15 (Vercel/Cloud Run)
- **Backend**: FastAPI or Express (Cloud Run/Railway)
- **Database**: PostgreSQL (Supabase)
- **Cache**: Redis (Upstash/Railway)
- **AI**: Claude API with structured output
- **Real-time**: Supabase subscriptions

### Key Design Decisions
1. **Hybrid Deployment**: Vercel (frontend) + Cloud Run (backend) for optimal performance
2. **AI Integration**: Structured output with Pydantic/Zod for type safety
3. **Real-time Updates**: Supabase subscriptions for live data
4. **Immutable Patterns**: Spread operators for predictable state
5. **Many Small Files**: High cohesion, low coupling

### Scalability Plan
- **10K users**: Current architecture sufficient
- **100K users**: Add Redis clustering, CDN for static assets
- **1M users**: Microservices architecture, separate read/write databases
- **10M users**: Event-driven architecture, distributed caching, multi-region

**Remember**: Good architecture enables rapid development, easy maintenance, and confident scaling. The best architecture is simple, clear, and follows established patterns.
30 changes: 2 additions & 28 deletions dot_claude/agents/code-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,37 +31,11 @@ When invoked:

### Security (CRITICAL)

These MUST be flagged — they can cause real damage:

- **Hardcoded credentials** — API keys, passwords, tokens, connection strings in source
- **SQL injection** — String concatenation in queries instead of parameterized queries
- **XSS vulnerabilities** — Unescaped user input rendered in HTML/JSX
- **Path traversal** — User-controlled file paths without sanitization
- **CSRF vulnerabilities** — State-changing endpoints without CSRF protection
- **Authentication bypasses** — Missing auth checks on protected routes
- **Insecure dependencies** — Known vulnerable packages
- **Exposed secrets in logs** — Logging sensitive data (tokens, passwords, PII)

```typescript
// BAD: SQL injection via string concatenation
const query = `SELECT * FROM users WHERE id = ${userId}`;

// GOOD: Parameterized query
const query = `SELECT * FROM users WHERE id = $1`;
const result = await db.query(query, [userId]);
```

```typescript
// BAD: Rendering raw user HTML without sanitization
// Always sanitize user content with DOMPurify.sanitize() or equivalent

// GOOD: Use text content or sanitize
<div>{userComment}</div>
```
Flag hardcoded credentials, SQL injection, XSS, path traversal, CSRF, auth bypasses, insecure dependencies, and secrets in logs. For detailed security review, delegate to the `security-reviewer` agent.

### Code Quality (HIGH)

- **Large functions** (>50 lines) — Split into smaller, focused functions
- **Large functions** (>100 lines) — Split into smaller, focused functions
- **Large files** (>800 lines) — Extract modules by responsibility
- **Deep nesting** (>4 levels) — Use early returns, extract helpers
- **Missing error handling** — Unhandled promise rejections, empty catch blocks
Expand Down
2 changes: 1 addition & 1 deletion dot_claude/agents/go-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ When invoked:
- **Mutex misuse**: Not using `defer mu.Unlock()`

### HIGH -- Code Quality
- **Large functions**: Over 50 lines
- **Large functions**: Over 100 lines
- **Deep nesting**: More than 4 levels
- **Non-idiomatic**: `if/else` instead of early return
- **Package-level variables**: Mutable global state
Expand Down
81 changes: 1 addition & 80 deletions dot_claude/agents/planner.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,85 +98,6 @@ Create detailed steps with:
6. **Think Incrementally**: Each step should be verifiable
7. **Document Decisions**: Explain why, not just what

## Worked Example: Adding Stripe Subscriptions

Here is a complete plan showing the level of detail expected:

```markdown
# Implementation Plan: Stripe Subscription Billing

## Overview
Add subscription billing with free/pro/enterprise tiers. Users upgrade via
Stripe Checkout, and webhook events keep subscription status in sync.

## Requirements
- Three tiers: Free (default), Pro ($29/mo), Enterprise ($99/mo)
- Stripe Checkout for payment flow
- Webhook handler for subscription lifecycle events
- Feature gating based on subscription tier

## Architecture Changes
- New table: `subscriptions` (user_id, stripe_customer_id, stripe_subscription_id, status, tier)
- New API route: `app/api/checkout/route.ts` — creates Stripe Checkout session
- New API route: `app/api/webhooks/stripe/route.ts` — handles Stripe events
- New middleware: check subscription tier for gated features
- New component: `PricingTable` — displays tiers with upgrade buttons

## Implementation Steps

### Phase 1: Database & Backend (2 files)
1. **Create subscription migration** (File: supabase/migrations/004_subscriptions.sql)
- Action: CREATE TABLE subscriptions with RLS policies
- Why: Store billing state server-side, never trust client
- Dependencies: None
- Risk: Low

2. **Create Stripe webhook handler** (File: src/app/api/webhooks/stripe/route.ts)
- Action: Handle checkout.session.completed, customer.subscription.updated,
customer.subscription.deleted events
- Why: Keep subscription status in sync with Stripe
- Dependencies: Step 1 (needs subscriptions table)
- Risk: High — webhook signature verification is critical

### Phase 2: Checkout Flow (2 files)
3. **Create checkout API route** (File: src/app/api/checkout/route.ts)
- Action: Create Stripe Checkout session with price_id and success/cancel URLs
- Why: Server-side session creation prevents price tampering
- Dependencies: Step 1
- Risk: Medium — must validate user is authenticated

4. **Build pricing page** (File: src/components/PricingTable.tsx)
- Action: Display three tiers with feature comparison and upgrade buttons
- Why: User-facing upgrade flow
- Dependencies: Step 3
- Risk: Low

### Phase 3: Feature Gating (1 file)
5. **Add tier-based middleware** (File: src/middleware.ts)
- Action: Check subscription tier on protected routes, redirect free users
- Why: Enforce tier limits server-side
- Dependencies: Steps 1-2 (needs subscription data)
- Risk: Medium — must handle edge cases (expired, past_due)

## Testing Strategy
- Unit tests: Webhook event parsing, tier checking logic
- Integration tests: Checkout session creation, webhook processing
- E2E tests: Full upgrade flow (Stripe test mode)

## Risks & Mitigations
- **Risk**: Webhook events arrive out of order
- Mitigation: Use event timestamps, idempotent updates
- **Risk**: User upgrades but webhook fails
- Mitigation: Poll Stripe as fallback, show "processing" state

## Success Criteria
- [ ] User can upgrade from Free to Pro via Stripe Checkout
- [ ] Webhook correctly syncs subscription status
- [ ] Free users cannot access Pro features
- [ ] Downgrade/cancellation works correctly
- [ ] All tests pass with 80%+ coverage
```

## When Planning Refactors

1. Identify code smells and technical debt
Expand All @@ -198,7 +119,7 @@ Each phase should be mergeable independently. Avoid plans that require all phase

## Red Flags to Check

- Large functions (>50 lines)
- Large functions (>100 lines)
- Deep nesting (>4 levels)
- Duplicated code
- Missing error handling
Expand Down
Loading