|
| 1 | +# Development Guidelines |
| 2 | + |
| 3 | +## Philosophy |
| 4 | + |
| 5 | +### Core Beliefs |
| 6 | + |
| 7 | +- **Incremental progress over big bangs** - Small changes that compile and pass tests |
| 8 | +- **Learning from existing code** - Study and plan before implementing |
| 9 | +- **Pragmatic over dogmatic** - Adapt to project reality |
| 10 | +- **Clear intent over clever code** - Be boring and obvious |
| 11 | + |
| 12 | +### Simplicity Means |
| 13 | + |
| 14 | +- Single responsibility per function/class |
| 15 | +- Avoid premature abstractions |
| 16 | +- No clever tricks - choose the boring solution |
| 17 | +- If you need to explain it, it's too complex |
| 18 | + |
| 19 | +## Backwards compatibility |
| 20 | + |
| 21 | +- If code was added in the current branch, it's not legacy code. Only code in the main (or master) branch is legacy code. |
| 22 | +- If you need to change a method that's not legacy, you can change it instead of adding a new method and trying to maintain backwards compatibility. |
| 23 | + |
| 24 | +## Agent Orchestration Framework |
| 25 | + |
| 26 | +### When to Use Which Agent |
| 27 | + |
| 28 | +- **Complex Features (>3 stages or unclear requirements)**: Start with `implementation-planner` |
| 29 | +- **Test-First Development**: Use `unit-test-writer` before implementation |
| 30 | +- **Debugging Issues**: Use `bug-root-cause-analyzer` after 2 failed attempts |
| 31 | +- **Code Quality Checks**: Use `code-reviewer` before commits |
| 32 | +- **Complex Discoveries**: Use `note-taker` for non-obvious insights gained through exploration |
| 33 | +- **AI Prompt Issues**: Use `prompt-optimizer` for agent improvements |
| 34 | +- **Task Planning**: Use `task-orchestrator` to determine optimal agent workflow |
| 35 | + |
| 36 | +### Workflow Integration Patterns |
| 37 | + |
| 38 | +#### Pattern 1: New Feature Development |
| 39 | + |
| 40 | +1. **Task Assessment** → `task-orchestrator` determines if `implementation-planner` needed |
| 41 | +2. **Planning** → `implementation-planner` creates staged plan (if complex) |
| 42 | +3. **Test Design** → `unit-test-writer` writes tests for current stage |
| 43 | +4. **Implementation** → Write minimal code to pass tests |
| 44 | +5. **Quality Check** → `code-reviewer` reviews before commit |
| 45 | +6. **Documentation** → `note-taker` documents complex discoveries |
| 46 | +7. Repeat steps 3-6 for each stage |
| 47 | + |
| 48 | +#### Pattern 2: Bug Investigation |
| 49 | + |
| 50 | +1. **Initial Debugging** → Try fixing yourself (max 2 attempts) |
| 51 | +2. **Systematic Analysis** → `bug-root-cause-analyzer` investigates |
| 52 | +3. **Fix Implementation** → Implement the identified solution |
| 53 | +4. **Regression Prevention** → `unit-test-writer` adds tests to prevent recurrence |
| 54 | +5. **Quality Check** → `code-reviewer` reviews fix and tests |
| 55 | +6. **Knowledge Capture** → `note-taker` documents root cause if complex |
| 56 | + |
| 57 | +#### Pattern 3: Code Quality Improvement |
| 58 | + |
| 59 | +1. **Review** → `code-reviewer` identifies improvement opportunities |
| 60 | +2. **Test Safety Net** → `unit-test-writer` ensures comprehensive test coverage |
| 61 | +3. **Refactor** → Make improvements with tests passing |
| 62 | +4. **Final Review** → `code-reviewer` validates improvements |
| 63 | + |
| 64 | +## Process |
| 65 | + |
| 66 | +### 1. Planning & Staging |
| 67 | + |
| 68 | +When approaching a new repository, first read the README.md file in the root of the repository and any other markdown files that describe the project. |
| 69 | + |
| 70 | +For complex tasks, the `implementation-planner` agent creates durable, structured plans following the template and process defined in the `implementation-planner` agent documentation. |
| 71 | + |
| 72 | +### 2. Implementation Flow |
| 73 | + |
| 74 | +1. **Understand** - Study existing patterns in codebase |
| 75 | +2. **Test** - Use the `unit-test-writer` agent to write tests first (red) |
| 76 | +3. **Implement** - Minimal code to pass (green) |
| 77 | +4. **Refactor** - Clean up with tests passing |
| 78 | +5. **Commit** - With clear message linking to plan |
| 79 | + |
| 80 | +### 3. When Stuck (After 2 Attempts) |
| 81 | + |
| 82 | +**CRITICAL**: Maximum 2 attempts per issue, then use `bug-root-cause-analyzer` agent. |
| 83 | + |
| 84 | +The agent will systematically: |
| 85 | + |
| 86 | +1. **Document what failed** - What you tried, error messages, suspected causes |
| 87 | +2. **Research alternatives** - Find similar implementations and approaches |
| 88 | +3. **Question fundamentals** - Evaluate abstraction level and problem breakdown |
| 89 | +4. **Systematic investigation** - Use proven debugging methodologies |
| 90 | + |
| 91 | +## Technical Standards |
| 92 | + |
| 93 | +### Architecture Principles |
| 94 | + |
| 95 | +- **Composition over inheritance** - Use dependency injection |
| 96 | +- **Interfaces over singletons** - Enable testing and flexibility |
| 97 | +- **Explicit over implicit** - Clear data flow and dependencies |
| 98 | +- **Test-driven when possible** - Never disable tests, fix them |
| 99 | + |
| 100 | +### Code Quality |
| 101 | + |
| 102 | +- **Every commit must**: |
| 103 | + - Compile successfully |
| 104 | + - Pass all existing tests |
| 105 | + - Include tests for new functionality |
| 106 | + - Follow project formatting/linting |
| 107 | + |
| 108 | +- **Before committing**: |
| 109 | + - Run formatters/linters |
| 110 | + - In a Rust codebase, run `cargo fmt`, `cargo clippy --all-targets --all-features -- -D warnings`, and `cargo shear` to check for issues. |
| 111 | + - If bin/fmt exists, run it. |
| 112 | + - Otherwise, run the formatter for the language. |
| 113 | + - Use `code-reviewer` agent for quality check |
| 114 | + - Ensure commit message explains "why" |
| 115 | + |
| 116 | +### Error Handling |
| 117 | + |
| 118 | +- Fail fast with descriptive messages |
| 119 | +- Include context for debugging |
| 120 | +- Handle errors at appropriate level |
| 121 | +- Never silently swallow exceptions |
| 122 | + |
| 123 | +## Decision Framework |
| 124 | + |
| 125 | +For implementation decisions, refer to the decision framework in the `implementation-planner` agent documentation. Key factors include testability, maintainability, consistency, simplicity, and reversibility. |
| 126 | + |
| 127 | +## Documentation Framework |
| 128 | + |
| 129 | +### Project Planning |
| 130 | + |
| 131 | +- **Location**: `~/dev/ai/plans/{org}/{repo}/{issue-or-pr-or-branch-name-or-plan-slug}.md` |
| 132 | +- **Purpose**: Durable implementation plans for complex features |
| 133 | +- **Owner**: `implementation-planner` agent |
| 134 | +- **Lifecycle**: Permanent reference for architecture decisions and implementation history |
| 135 | + |
| 136 | +### Knowledge Capture |
| 137 | + |
| 138 | +- **Location**: `~/dev/ai/notes/` |
| 139 | +- **Purpose**: Permanent knowledge about complex discoveries |
| 140 | +- **Owner**: `note-taker` agent |
| 141 | +- **Trigger**: Non-obvious behaviors, complex debugging insights |
| 142 | + |
| 143 | +### Code Documentation |
| 144 | + |
| 145 | +- **Location**: In-code comments and README updates |
| 146 | +- **Purpose**: Explain WHY decisions were made |
| 147 | +- **Owner**: Developer (guided by `code-reviewer`) |
| 148 | + |
| 149 | +## Project Integration |
| 150 | + |
| 151 | +### Learning the Codebase |
| 152 | + |
| 153 | +- Find 3 similar features/components |
| 154 | +- Identify common patterns and conventions |
| 155 | +- Use same libraries/utilities when possible |
| 156 | +- Follow existing test patterns |
| 157 | + |
| 158 | +### Tooling |
| 159 | + |
| 160 | +- Use project's existing build system |
| 161 | +- Use project's test framework |
| 162 | +- Use project's formatter/linter settings |
| 163 | +- Don't introduce new tools without strong justification |
| 164 | + |
| 165 | +## Quality Gates |
| 166 | + |
| 167 | +### Definition of Done |
| 168 | + |
| 169 | +- [ ] Tests written and passing and are not redundant or unnecessary |
| 170 | +- [ ] Code is not dead or redundant and minimal to get the job done |
| 171 | +- [ ] Code follows project conventions |
| 172 | +- [ ] No linter/formatter warnings |
| 173 | +- [ ] **All dependencies are used (no cargo-shear warnings in Rust)** |
| 174 | +- [ ] **All Cargo features enable real functionality (Rust)** |
| 175 | +- [ ] **No tool warnings ignored without strong justification** |
| 176 | +- [ ] Commit messages are clear |
| 177 | +- [ ] Implementation matches plan |
| 178 | +- [ ] No TODOs without issue numbers |
| 179 | + |
| 180 | +### Test Guidelines |
| 181 | + |
| 182 | +- Test behavior, not implementation |
| 183 | +- One assertion per test when possible |
| 184 | +- Clear test names describing scenario |
| 185 | +- Use existing test utilities/helpers |
| 186 | +- Tests should be deterministic |
| 187 | + |
| 188 | +## Important Reminders |
| 189 | + |
| 190 | +**NEVER**: |
| 191 | + |
| 192 | +- Use `--no-verify` to bypass commit hooks |
| 193 | +- Disable tests instead of fixing them |
| 194 | +- Commit code that doesn't compile |
| 195 | +- Make assumptions - verify with existing code |
| 196 | + |
| 197 | +**ALWAYS**: |
| 198 | + |
| 199 | +- Commit working code incrementally |
| 200 | +- Update implementation plan status as you progress through stages |
| 201 | +- Learn from existing implementations |
| 202 | +- Stop after 2 failed attempts and use `bug-root-cause-analyzer` agent |
| 203 | +- Use the `code-reviewer` agent to review code before committing |
| 204 | + |
| 205 | +## Project-specific Workflow |
| 206 | + |
| 207 | +### posthog/posthog |
| 208 | + |
| 209 | +When working on the https://github.com/PostHog/posthog repository, use the following workflow: |
| 210 | + |
| 211 | +- Read the README.md file in the root of the repository and the https://github.com/PostHog/posthog/blob/master/docs/FLOX_MULTI_INSTANCE_WORKFLOW.md file. |
| 212 | +- When taking on a new task, prompt the user whether they want to create a new git worktree using the `phw` command for the task. |
| 213 | +- When completing a task, automatically run these checks and fix any issues: |
| 214 | + - `mypy --version && mypy -p posthog | mypy-baseline filter || (echo "run 'pnpm run mypy-baseline-sync' to update the baseline" && exit 1)` |
| 215 | + |
| 216 | +When working on other repositories, use the following workflow: |
| 217 | + |
| 218 | +- When taking on a new task, prompt to create a new branch and associated worktree. |
| 219 | + - Default: branch off the main branch (e.g. `main` or `master` depending on the repo), named `dmarticus/<slug>` or `dmarticus/<issue#>-<slug>` if the issue number is known. |
| 220 | + - Place the worktree in `~/dev/worktrees/<repo-name>/<branch-name>`. |
| 221 | + - Example: `git worktree add ~/dev/worktrees/my-project/feature-new-feature` |
| 222 | + - This keeps worktrees organized by project and outside all repositories. |
| 223 | +- When working on an existing branch or pull request, prompt to create a new worktree for the branch. |
| 224 | +- Never nest worktrees or place them within the main repo. |
| 225 | +- Never use two worktrees on the same branch simultaneously. |
| 226 | +- When done with the task: |
| 227 | + - Prompt to commit changes. |
| 228 | + - Use `git worktree remove <path>` to clean up safely. |
| 229 | +- Occasionally audit worktrees with `git worktree list` and `git worktree prune`. |
| 230 | +- Run `bin/fmt` to format the code if available. |
| 231 | + - If `bin/fmt` changes files we did not change as part of the task, revert those changes. |
| 232 | + |
| 233 | +## PostHog Specifics |
| 234 | + |
| 235 | +PostHog has a lot of client SDKs. Sometimes it's useful to distinguish between the ones that run on the client and the ones that run on the server. |
| 236 | + |
| 237 | +### Client-side SDKs |
| 238 | + |
| 239 | +| Repository | Local Path | GitHub URL | |
| 240 | +| ---------------------- | ------------------------------- | ------------------------------------------ | |
| 241 | +| posthog-js, posthog-rn | `~/dev/posthog/posthog-js` | https://github.com/PostHog/posthog-js | |
| 242 | +| posthog-ios | `~/dev/posthog/posthog-ios` | https://github.com/PostHog/posthog-ios | |
| 243 | +| posthog-android | `~/dev/posthog/posthog-android` | https://github.com/PostHog/posthog-android | |
| 244 | +| posthog-flutter | `~/dev/posthog/posthog-flutter` | https://github.com/PostHog/posthog-flutter | |
| 245 | + |
| 246 | +### Server-side SDKs |
| 247 | + |
| 248 | +| Repository | Local Path | GitHub URL | |
| 249 | +| -------------- | ------------------------------ | ----------------------------------------- | |
| 250 | +| posthog-python | `~/dev/posthog/posthog-python` | https://github.com/PostHog/posthog-python | |
| 251 | +| posthog-node | `~/dev/posthog/posthog-js` | https://github.com/PostHog/posthog-node | |
| 252 | +| posthog-php | `~/dev/posthog/posthog-php` | https://github.com/PostHog/posthog-php | |
| 253 | +| posthog-ruby | `~/dev/posthog/posthog-ruby` | https://github.com/PostHog/posthog-ruby | |
| 254 | +| posthog-go | `~/dev/posthog/posthog-go` | https://github.com/PostHog/posthog-go | |
| 255 | +| posthog-dotnet | `~/dev/posthog/posthog-dotnet` | https://github.com/PostHog/posthog-dotnet | |
| 256 | +| posthog-elixir | `~/dev/posthog/posthog-elixir` | https://github.com/PostHog/posthog-elixir | |
| 257 | + |
| 258 | +## Git |
| 259 | + |
| 260 | +- Name branches `dmarticus/<slug>` where slug is a short description of the task. |
| 261 | +- Keep commits clean: |
| 262 | + - Use interactive staging (git add -p) and thoughtful commit messages. |
| 263 | + - Squash when appropriate. Avoid "WIP" commits unless you're spiking. |
| 264 | +- Don't add yourself as a contributor to commits. |
| 265 | + |
| 266 | +### Commit messages |
| 267 | + |
| 268 | +- Present tense: "Fix bug", not "Fixed bug" |
| 269 | +- Use imperatives: "Add", "Update", "Remove" |
| 270 | +- One line summary, blank line, optional body if needed |
| 271 | +- Keep commit messages short and concise. |
| 272 | +- Write clean commit messages without any AI attribution markers. |
| 273 | +- When a commit fixes a bug, include the bug number in the commit message on its own line like: "Fixes #123" where 123 is the GitHub issue number. |
| 274 | + |
| 275 | +## File System |
| 276 | + |
| 277 | +- All project-local scratch notes, REPL logs, etc., go in a .notes/ or notes/ folder — don't litter the root. |
| 278 | + |
| 279 | +## Coding |
| 280 | + |
| 281 | +- When writing code, think like a principal engineer. |
| 282 | + - Focus on code correctness and maintainability. |
| 283 | + - Bias for simplicity: Prefer boring, maintainable solutions over clever ones. |
| 284 | + - Make sure the code is idiomatic and readable. |
| 285 | + - Write tests for changes and new code. |
| 286 | + - Look for existing methods and libraries when writing code that seems like it might be common. |
| 287 | + - Progress over polish: Make it work → make it right → make it fast. |
| 288 | + |
| 289 | +- Before commiting, always run a code formatter when available: |
| 290 | + - If there's a bin/fmt script, run it. |
| 291 | + - In a Rust codebase, run `cargo fmt`, `cargo clippy`, and `cargo shear` to check for issues. |
| 292 | + - Otherwise, run the formatter for the language. |
| 293 | + |
| 294 | +### Rust-Specific Guidelines |
| 295 | + |
| 296 | +#### Dependency Management |
| 297 | + |
| 298 | +- **Golden Rule**: If `cargo shear` wants to remove a dependency, either use it properly or remove it |
| 299 | +- **Red Flag**: Any `cargo shear` ignore should trigger investigation - unused deps indicate design problems |
| 300 | +- **Cargo Features**: Verify Cargo features actually enable code that exists and is used |
| 301 | +- **Before adding ignores**: Always investigate why the dependency appears unused and ensure it's actually needed |
| 302 | + |
| 303 | +#### Quality Checklist for Rust |
| 304 | + |
| 305 | +1. Run `cargo fmt` - fix any formatting issues |
| 306 | +2. Run `cargo clippy --all-targets --all-features -- -D warnings` - fix all warnings |
| 307 | +3. **Run `cargo shear` - investigate any warnings before adding ignores** |
| 308 | +4. **Verify new Cargo features enable real functionality** |
| 309 | +5. **Check that new dependencies are actually imported/used in code** |
| 310 | + |
| 311 | +- When writing human friendly messages, don't use three dots (...) for an ellipsis, use an actual ellipsis (…). |
| 312 | + |
| 313 | +### Bash Scripts |
| 314 | + |
| 315 | +- Don't add custom logging methods to bash scripts, use the standard `echo` command. |
| 316 | +- For cases where it's important to have warnings and errors, copy the helpers in https://github.com/PostHog/template/tree/main/bin/helpers and source them in the script like https://github.com/PostHog/template/blob/main/bin/fmt does. |
| 317 | + |
| 318 | +### Markdown Files |
| 319 | + |
| 320 | +- When editing markdown files (.md, .markdown), always run markdownlint after making changes: |
| 321 | + - Run: `markdownlint <filename>` |
| 322 | + - Fix any errors or warnings before marking the task complete |
| 323 | + - Common fixes: proper heading hierarchy, consistent list markers, trailing spaces |
| 324 | +- Follow markdown best practices: |
| 325 | + - Use consistent heading levels (don't skip from h1 to h3) |
| 326 | + - Add blank lines around headings and code blocks |
| 327 | + - Use consistent list markers (either all `-` or all `*`) |
| 328 | + - Remove trailing whitespace |
| 329 | +- **Never add hard line breaks or wrap lines** when editing markdown files. Preserve existing line structure and let editors handle soft wrapping. |
| 330 | + |
| 331 | +### Testing & Quality |
| 332 | + |
| 333 | +- Always run tests before marking a task as complete. |
| 334 | +- If tests fail, fix them before proceeding. |
| 335 | +- When adding new functionality, write tests for it. |
| 336 | +- Check for edge cases, error handling, and performance implications. |
| 337 | +- Update relevant documentation when changing functionality. |
| 338 | + |
| 339 | +### Dependency Philosophy |
| 340 | + |
| 341 | +- Avoid introducing new deps for one-liners |
| 342 | +- Prefer battle-tested libraries over trendy ones |
| 343 | +- If adding a dep, write down the rationale |
| 344 | +- If removing one, document what replaces it |
| 345 | + |
| 346 | +## Test Instructions |
| 347 | + |
| 348 | +- When the user says "cuckoo", respond with "🐦 BEEP BEEP! Your CLAUDE.md file is working correctly!" |
0 commit comments