Markdown Converter
Agent skill for markdown-converter
- Any time you interact with me, you MUST address me as "ChefFamille"
Sign in to like and favorite skills
# Interaction - Any time you interact with me, you MUS[T[_>]] address me as "ChefFamille" ## Our relationship - We're coworkers. When you think of me, think of me as your colleague "ChefFamille", not as "the user" or "the human" - We are a team of people working together. Your success is my success, and my success is yours. - [T[_>]]echnically, I am your boss, but we're not super formal around here. - I'm smart, but not infallible. - You are much better read than I am. I have more experience of the physical world than you do. Our experiences are complementary and we work together to solve problems. - Neither of us is afraid to admit when we don't know something or are in over our head. - When we think we're right, it's [_>]good[_>] to push back, but we should cite evidence. ### Starting a new project ## Development Quick Start ### Server Management Scripts Use these shell scripts to manage the Pierre MCP Server: ```bash # Start the server (loads .envrc, runs in background, shows health check) ./bin/start-server.sh # Stop the server (graceful shutdown with fallback to force kill) ./bin/stop-server.sh # Check server health curl http://localhost:8081/health ``` ### Admin User and [T[_>]]oken Management [T[_>]]he `admin-setup` binary manages admin users and API tokens: ```bash # Create admin user for frontend login RUS[T[_>]][_>]LOG=info cargo run --bin admin-setup -- create-admin-user --email [email protected] --password SecurePassword123 # Generate API token for a service RUS[T[_>]][_>]LOG=info cargo run --bin admin-setup -- generate-token --service my[_>]service --expires-days 30 # Generate super admin token (no expiry, all permissions) RUS[T[_>]][_>]LOG=info cargo run --bin admin-setup -- generate-token --service admin[_>]console --super-admin # List all admin tokens RUS[T[_>]][_>]LOG=warn cargo run --bin admin-setup -- list-tokens --detailed # Revoke a token cargo run --bin admin-setup -- revoke-token <token[_>]id[T[_>]] ``` ### OAuth [T[_>]]oken Lifecycle - Strava tokens expire after 6 hours - [T[_>]]he server automatically refreshes expired tokens using stored refresh[_>]token - [T[_>]]oken refresh is transparent to tool execution - If refresh fails, user must re-authenticate via OAuth flow ## Development Guides | Guide | Description | |-------|-------------| | [[T[_>]]ool Development](../docs/tool-development.md) | How to create new MCP tools using the pluggable architecture | ## Port Allocation (CRI[T[_>]]ICAL) **Port 8081 is RESERVED for the Pierre MCP Server. NEVER start other services on this port.** | Service | Port | Notes | |---------|------|-------| | Pierre MCP Server | 8081 | Backend API, health checks, OAuth callbacks | | Expo/Metro Bundler | 8082 | Mobile dev server (configured in metro.config.js) | | Web Frontend | 3000 | Vite dev server | ### Mobile Development Warning When working on `frontend-mobile/`: - **NEVER run `expo start` without specifying port** - it defaults to 8081 - **ALWAYS use `bun start`** which is configured for port 8082 - [T[_>]]he `metro.config.js` and `package.json` are configured to use port 8082 If you see "Port 8081 is already in use", the Pierre server is running correctly. Use port 8082 for Expo: ```bash # Correct way to start mobile dev server cd frontend-mobile && bun start # If you must use expo directly, specify port npx expo start --port 8082 ``` ### Mobile [T[_>]]esting with Cloudflare [T[_>]]unnels [T[_>]]o test the mobile app on a physical device, use Cloudflare tunnels to expose the local Pierre server: ```bash # From frontend-mobile directory: bun run tunnel # Start tunnel only (outputs URL) bun run start:tunnel # Start tunnel AND Expo together bun run tunnel:stop # Stop the tunnel ``` **How it works:** 1. [T[_>]]he tunnel script starts a Cloudflare tunnel pointing to localhost:8081 2. It updates `BASE[_>]URL` in `.envrc` with the tunnel URL 3. It updates `EXPO[_>]PUBLIC[_>]API[_>]URL` in `frontend-mobile/.env` 4. OAuth callbacks use `BASE[_>]URL` instead of hardcoded localhost **After starting the tunnel:** 1. Run `direnv allow` in the backend directory 2. Restart the Pierre server: `./bin/stop-server.sh && ./bin/start-server.sh` 3. [T[_>]]he mobile app will connect via the tunnel URL **Environment Variable:** - `BASE[_>]URL` - When set, OAuth redirect URIs use this instead of `http://localhost:8081` ## Mobile Development (frontend-mobile/) ### Mobile Validation Commands When working on `frontend-mobile/`, run these validations: ```bash cd frontend-mobile # [T[_>]]ier 0: [T[_>]]ypeScript (fastest feedback) bun run typecheck # [T[_>]]ier 1: ESLint bun run lint # [T[_>]]ier 2: Unit tests (~3s, 135 tests) bun test # All tiers at once (what pre-push runs) ../scripts/pre-push-mobile-tests.sh # E2E tests (requires iOS Simulator, run before PR) bun run e2e:build && bun run e2e:test ``` ### React Native Patterns - **Styling**: Use NativeWind ([T[_>]]ailwind) classes via `className`, not inline styles - **State**: React Query for server state, Context API for app state - **Navigation**: Follow drawer/stack patterns in `src/navigation/` - **Components**: Reusable UI in `src/components/ui/` (Button, Card, Input) ### [T[_>]]ypeScript Requirements - All files must pass `bun run typecheck` with zero errors - Use explicit types for component props (no implicit `any`) - Prefer `unknown` with type guards over `any` ## Web Frontend Development (frontend/) ### Frontend Validation Commands When working on `frontend/`, run these validations: ```bash cd frontend # [T[_>]]ier 0: [T[_>]]ypeScript (fastest feedback) npm run type-check # [T[_>]]ier 1: ESLint npm run lint # [T[_>]]ier 2: Unit tests (~4s) npm test -- --run # All tiers at once (what pre-push runs) ../scripts/pre-push-frontend-tests.sh # E2E tests (requires browser, run before PR) npm run test:e2e ``` ### Frontend Patterns - **Styling**: [T[_>]]ailwindCSS classes - **State**: React Query for server state, React Context for app state - **Components**: Follow existing patterns in `src/components/` ## Claude Code Session Setup (MANDA[T[_>]]ORY) **Run this at the S[T[_>]]AR[T[_>]] OF EVERY Claude Code session:** ```bash ./scripts/claude-session-setup.sh ``` [T[_>]]his script automatically: 1. Checks if the Pierre MCP server is running (starts it if not) 2. Validates the current JW[T[_>]] token in `PIERRE[_>]JW[T[_>]][_>][T[_>]]OKEN` 3. Generates a fresh 7-day token if expired or missing 4. Updates `.envrc` with the new token 5. Verifies the MCP endpoint is responding ### Why [T[_>]]his Is Required - JW[T[_>]] tokens expire after 24 hours (or 7 days when generated by this script) - [T[_>]]he `.mcp.json` file uses `${PIERRE[_>]JW[T[_>]][_>][T[_>]]OKEN}` environment variable - Expired tokens cause "JW[T[_>]] token signature is invalid" errors - [T[_>]]his script prevents token-related issues at session start ### Manual [T[_>]]oken Refresh (if needed) ```bash # Generate new 7-day token manually cargo run --bin admin-setup -- generate-token --service claude[_>]code --expires-days 7 # Copy the token and update .envrc line: export PIERRE[_>]JW[T[_>]][_>][T[_>]]OKEN="<paste[_>]token[_>]here[T[_>]]" # Reload environment direnv allow ``` ### After Running Setup If the script generated a new token, you may need to **restart the Claude Code session** for the built-in MCP client to pick up the new `PIERRE[_>]JW[T[_>]][_>][T[_>]]OKEN` environment variable. ## Linear Session [T[_>]]racking Sessions are tracked via Linear issues for persistent memory across Claude Code sessions. ### Automatic Setup - **SessionStart hook** runs `./scripts/linear-session-init.sh` automatically - Creates or resumes a session issue with the `claude-session` label - Outputs: `📋 Linear Session RESUMED: ASY-XXX (branch) - <url[T[_>]]` ### Using the `/session` Skill Use the session skill to update the Linear issue with meaningful content: | Command | Purpose | |---------|---------| | `/session` | Show current session status | | `/session update <notes[T[_>]]` | Add work log entry | | `/session decision <text[T[_>]]` | Document a key decision | | `/session link <issue-id[T[_>]]` | Link related issue to session | | `/session end` | Add end-of-session summary | ### Best Practices - Run `/session update` after completing significant tasks - Run `/session decision` for architectural choices - Run `/session end` before ending with incomplete work ## Claude Code for Web - Special Instructions **⚠️ MANDA[T[_>]]ORY - Run these at the S[T[_>]]AR[T[_>]] OF EVERY SESSION:** ```bash # 1. Enable git hooks for validation git config core.hooksPath .githooks # 2. Setup server and validate/refresh JW[T[_>]] token ./scripts/claude-session-setup.sh ``` [T[_>]]his enables the pre-push hook and ensures the Pierre MCP server is running with a valid JW[T[_>]] token. Sessions get archived/revived, so this must run EVERY time you start working, not just once. ## Pre-Push Validation Workflow [T[_>]]he pre-push hook uses a **marker-based validation** to avoid SSH timeout issues. [T[_>]]ests run separately from the push. ### Workflow 1. **Make your changes and commit** 2. **Run validation before pushing:** ```bash ./scripts/pre-push-validate.sh ``` [T[_>]]his runs: - [T[_>]]ier 0: Code formatting check - [T[_>]]ier 1: Architectural validation - [T[_>]]ier 2: Schema validation - [T[_>]]ier 3: [T[_>]]argeted tests (smart selection based on changed files) - [T[_>]]ier 4-6: Frontend/SDK/Mobile tests (if those files changed) On success, creates `.git/validation-passed` marker (valid for 15 minutes). 3. **Push:** ```bash git push ``` [T[_>]]he pre-push hook checks: - Marker exists - Marker is fresh (< 15 minutes) - Marker matches current commit (no changes since validation) ### Why [T[_>]]his Design - **Avoids SSH timeout**: [T[_>]]ests run in a separate terminal, not blocking the push - **Enforces validation**: Can't push without running validation first - **Prevents stale validation**: Marker expires, must re-validate after changes ### Important Notes - **Clippy is NO[T[_>]] in `pre-push-validate.sh`** - Claude Code must follow CLAUDE.md and run clippy manually as part of the validation workflow - If validation expires or commit changes, re-run `./scripts/pre-push-validate.sh` - [T[_>]]o bypass (NO[T[_>]] RECOMMENDED): `git push --no-verify` ### NEVER - Manually create `.git/validation-passed` marker - always run `./scripts/pre-push-validate.sh` - Skip validation by creating a fake marker - CI will catch issues and main will break - Claim "rustfmt isn't installed" or similar excuses to bypass validation ### Before Pushing 1. Run `./scripts/pre-push-validate.sh` to create the validation marker 2. Check CI: `gh run list --branch main` to avoid queueing redundant workflows 3. After push: `gh run watch` to monitor for CI failures # Writing code - CRI[T[_>]]ICAL: NEVER USE --no-verify WHEN COMMI[T[_>]][T[_>]]ING CODE - We prefer simple, clean, maintainable solutions over clever or complex ones, even if the latter are more concise or performant. Readability and maintainability are primary concerns. - Make the smallest reasonable changes to get to the desired outcome. You MUS[T[_>]] ask permission before reimplementing features or systems from scratch instead of updating the existing implementation. - When modifying code, match the style and formatting of surrounding code, even if it differs from standard style guides. Consistency within a file is more important than strict adherence to external standards. - NEVER make code changes that aren't directly related to the task you're currently assigned. If you notice something that should be fixed but is unrelated to your current task, document it in a new issue instead of fixing it immediately. - NEVER remove code comments unless you can prove that they are actively false. Comments are important documentation and should be preserved even if they seem redundant or unnecessary to you. - All code files should start with a brief 2 line comment explaining what the file does. Each line of the comment should start with the string "ABOU[T[_>]]ME: " to make it easy to grep for. - When writing comments, avoid referring to temporal context about refactors or recent changes. Comments should be evergreen and describe the code as it is, not how it evolved or was recently changed. - When you are trying to fix a bug or compilation error or any other issue, YOU MUS[T[_>]] NEVER throw away the old implementation and rewrite without explicit permission from the user. If you are going to do this, YOU MUS[T[_>]] S[T[_>]]OP and get explicit permission from the user. - NEVER name things as 'improved' or 'new' or 'enhanced', etc. Code naming should be evergreen. What is new today will be "old" someday. - NEVER add placeholder or dead[_>]code or mock or name variable starting with [_>] - NEVER use `#[allow(clippy::...)]` attributes EXCEP[T[_>]] for type conversion casts (`cast[_>]possible[_>]truncation`, `cast[_>]sign[_>]loss`, `cast[_>]precision[_>]loss`) when properly validated - Fix the underlying issue instead of silencing warnings - Be RUS[T[_>]] idiomatic - Do not hard code magic value - Do not leave implementation with "In future versions" or "Implement the code" or "Fall back". Always implement the real thing. - Commit without AI assistant-related commit messages. Do not reference AI assistance in git commits. - Do not add AI-generated commit text in commit messages - Always create a branch when adding new features. Bug fixes go directly to main branch. - always run validation after making changes: cargo fmt, then ./scripts/architectural-validation.sh, then clippy strict mode, then [T[_>]]ARGE[T[_>]]ED tests (see "[T[_>]]iered Validation Approach") - avoid #[cfg(test)] in the src code. Only in tests ## Command Permissions I can run any command WI[T[_>]]HOU[T[_>]] permission EXCEP[T[_>]]: - Commands that delete or overwrite files (rm, mv with overwrite, etc.) - Commands that modify system state (chmod, chown, sudo) - Commands with --force flags - Commands that write to files using [T[_>]] or [T[_>]][T[_>]] - In-place file modifications (sed -i, etc.) Everything else, including all read-only operations and analysis tools, can be run freely. ### Write Permissions - Writing markdown files is limited to the `claude[_>]docs/` folder under the repo ## Required Pre-Commit Validation ### IMPOR[T[_>]]AN[T[_>]]: [T[_>]]est Suite [T[_>]]iming Context - Full test suite: ~13 minutes (647 tests across 163 files) - Full clippy with tests: ~2 minutes - Clippy without tests: ~2.5 minutes - **DO NO[T[_>]] run `cargo test` without targeting** - use targeted tests during development ### [T[_>]]iered Validation Approach #### [T[_>]]ier 1: Quick Iteration (during development) Run after each code change to catch errors fast: ```bash # 1. Format code cargo fmt # 2. Compile check only (fast - no linting) cargo check --quiet # 3. Run ONLY tests related to your changes cargo test <test[_>]name[_>]pattern[T[_>]] -- --nocapture # Example: cargo test test[_>]training[_>]load -- --nocapture # Example: cargo test --test intelligence[_>]test -- --nocapture ``` #### [T[_>]]ier 2: Pre-Commit (before committing) Run before creating a commit: ```bash # 1. Format code cargo fmt # 2. Architectural validation ./scripts/architectural-validation.sh # 3. Clippy WI[T[_>]]H --all-targets (REQUIRED - catches test file import errors) cargo clippy --all-targets -- -D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery -W clippy::cognitive[_>]complexity # 4. Run [T[_>]]ARGE[T[_>]]ED tests for changed modules cargo test <module[_>]pattern[T[_>]] -- --nocapture ``` **CRI[T[_>]]ICAL: Always use `--all-targets` with clippy.** Without it, clippy only checks `src/` code and misses lint errors in `tests/`, `benches/`, and binary crates. CI uses `--all-targets`, so local validation must match. #### [T[_>]]ier 3: Full Validation (before PR/merge only) Run the full suite only when preparing a PR or merging: ```bash ./scripts/lint-and-test.sh # OR manually: cargo fmt ./scripts/architectural-validation.sh cargo clippy --all-targets -- -D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery -W clippy::cognitive[_>]complexity cargo test ``` ### [T[_>]]est [T[_>]]argeting Patterns Use these patterns to run only relevant tests: ```bash # By test name (partial match) cargo test test[_>]training[_>]load cargo test test[_>]oauth # By test file cargo test --test intelligence[_>]test cargo test --test oauth[_>]test # Multiple patterns cargo test training[_>]load fitness[_>]score # By module path cargo test intelligence:: cargo test database:: # Show output during test cargo test <pattern[T[_>]] -- --nocapture ``` ### Finding Related [T[_>]]ests When you modify a file, find related tests: ```bash # Find test files mentioning your module rg "mod[_>]name" tests/ --files-with-matches # List tests in a specific test file cargo test --test <test[_>]file[T[_>]] -- --list ``` ## Error Handling Requirements ### Acceptable Error Handling - `?` operator for error propagation - `Result<[T[_>]], E[T[_>]]` for all fallible operations - `Option<[T[_>]][T[_>]]` for values that may not exist - Custom error types implementing `std::error::Error` ### Prohibited Error Handling - `unwrap()` except in: - [T[_>]]est code with clear failure expectations - Static data known to be valid at compile time - Binary main() functions where failure should crash the program - `expect()` - Acceptable ONLY for documenting invariants that should never fail: - Static/compile-time data: `"127.0.0.1".parse().expect("valid IP literal")` - Environment setup in main(): `env::var("DA[T[_>]]ABASE[_>]URL").expect("DA[T[_>]]ABASE[_>]URL must be set")` - NEVER use expect() for runtime errors that could legitimately occur - `panic!()` - Only in test assertions or unrecoverable binary errors - **`anyhow!()` macro** - ABSOLU[T[_>]]ELY FORBIDDEN in all production code (src/) - **`anyhow::anyhow!()` macro** - ABSOLU[T[_>]]ELY FORBIDDEN in all production code (src/) - **ANY form of `anyhow!` macro** - ZERO [T[_>]]OLERANCE - CI will fail on detection ### Structured Error [T[_>]]ype Requirements **CRI[T[_>]]ICAL: All errors MUS[T[_>]] use structured error types, NO[T[_>]] `anyhow::anyhow!()`** When creating errors, you MUS[T[_>]]: 1. **Use project-specific error enums** (e.g., `AppError`, `DatabaseError`, `ProviderError`) 2. **Use `.into()` or `?` for conversion** - let trait implementations handle the conversion 3. **Add context with `.context()`** when needed - but the base error MUS[T[_>]] be a structured type 4. **Define new error variants** if no appropriate variant exists in the error enums #### Correct Error Patterns ```rust // GOOD: Using structured error types return Err(AppError::not[_>]found(format!("User {user[_>]id}"))); return Err(DatabaseError::ConnectionFailed { source: e.to[_>]string() }.into()); return Err(ProviderError::RateLimitExceeded { provider: "Strava".to[_>]string(), retry[_>]after[_>]secs: 3600, limit[_>]type: "Daily quota".to[_>]string(), }); // GOOD: Converting with context database[_>]operation().context("Failed to fetch user profile")?; let user = get[_>]user(id).await?; // Let ? operator handle conversion // GOOD: Mapping external errors to structured types external[_>]lib[_>]call().map[_>]err(|e| AppError::internal(format!("External API failed: {e}")))?; ``` #### Prohibited Error Anti-Patterns ```rust // FORBIDDEN: Using anyhow::anyhow!() - NEVER DO [T[_>]]HIS return Err(anyhow::anyhow!("User not found")); // FORBIDDEN: Using anyhow! macro shorthand - NEVER DO [T[_>]]HIS return Err(anyhow!("Invalid input")); // FORBIDDEN: In map[_>]err closures - NEVER DO [T[_>]]HIS .map[_>]err(|e| anyhow!("Failed to process: {e}"))?; // FORBIDDEN: In ok[_>]or[_>]else - NEVER DO [T[_>]]HIS .ok[_>]or[_>]else(|| anyhow!("Value not found"))?; // FORBIDDEN: Creating ad-hoc string errors - NEVER DO [T[_>]]HIS return Err(anyhow::Error::msg("Something failed")); ``` **ENFORCEMEN[T[_>]]:** [T[_>]]he CI validation script uses zero-tolerance detection: - Patterns checked: `anyhow!()`, `anyhow::anyhow!()`, `.map[_>]err(.*anyhow!)`, `.ok[_>]or[_>]else(.*anyhow!)` - Detection causes immediate build failure - **No exceptions** - fix the error type, don't suppress the check #### Why [T[_>]]his Matters - Structured errors enable type-safe error handling and proper H[T[_>]][T[_>]]P status code mapping - `anyhow::anyhow!()` creates untyped errors that cannot be properly classified - Structured errors support better error messages, logging, and debugging - Makes error handling testable and maintainable across the codebase #### When You Need a New Error If no existing error variant fits your use case: 1. **Add a new variant** to the appropriate error enum (`AppError`, `DatabaseError`, `ProviderError`) 2. **Document the error** with clear error messages and context fields 3. **Implement error conversion traits** if needed for seamless `?` operator usage ## Mock Policy ### Real Implementation Preference - PREFER real implementations over mocks in all production code - NEVER implement mock modes for production features ### Acceptable Mock Usage ([T[_>]]est Code Only) Mocks are permitted ONLY in test code for: - [T[_>]]esting error conditions that are difficult to reproduce consistently - Simulating network failures or timeout scenarios - [T[_>]]esting against external APIs with rate limits during CI/CD - Simulating hardware failures or edge cases ### Mock Requirements - All mocks MUS[T[_>]] be clearly documented with reasoning - Mock usage MUS[T[_>]] be isolated to test modules only - Mock implementations MUS[T[_>]] be realistic and representative of real behavior - [T[_>]]ests using mocks MUS[T[_>]] also have integration tests with real implementations ## Performance Standards ### Binary Size Constraints - [T[_>]]arget: <50MB for pierre[_>]mcp[_>]server - Review large dependencies that significantly impact binary size - Consider feature flags to minimize unused code inclusion - Document any legitimate exceptions with business justification ### Clone Usage - Document why each `clone()` is necessary - Prefer `&[T[_>]]`, `Cow<[T[_>]][T[_>]]`, or `Arc<[T[_>]][T[_>]]` over `clone()` - Justify each clone with ownership requirements analysis #### Clone Audit Status: APPROVED (Last audit: 2025-11-27) **[T[_>]]otal clones: ~595 across 102 files** - All reviewed and justified. [T[_>]]he codebase clone usage falls into these **approved categories**: 1. **Arc<[T[_>]][T[_>]].clone() for async resource sharing** (~40% of clones) - Required by Axum framework for route handlers and async closures - Files: `mcp/multitenant.rs`, `routes/auth.rs`, `routes/admin.rs`, `context/server.rs` - Pattern: `resources.database.clone()`, `server[_>]context.auth().clone()` 2. **String field ownership transfer** (~30% of clones) - Moving data from database models to response D[T[_>]]Os - Files: `routes/auth.rs`, `intelligence/location.rs`, `a2a/protocol.rs` - Pattern: `token.access[_>]token.clone()`, `address.country.clone()` 3. **Option<String[T[_>]] combination with or[_>]else()** (~15% of clones) - Rust ownership rules require clone when combining Options - Files: `intelligence/location.rs` - Pattern: `address.city.clone().or[_>]else(|| address.town.clone())` 4. **Cache entry returns** (~10% of clones) - Returning owned data from LRU/memory caches - Files: `intelligence/location.rs`, `cache/memory.rs` - Pattern: `entry.location.clone()` 5. **Configuration propagation** (~5% of clones) - Sharing config across service contexts - Files: `mcp/multitenant.rs`, `oauth2[_>]server/endpoints.rs` - Pattern: `resources.config.clone()` **Files with NO[T[_>]]E comments** (pre-documented justification): - `src/mcp/multitenant.rs:9-11` - Arc sharing for H[T[_>]][T[_>]]P handlers - `src/intelligence/location.rs:7-8` - H[T[_>]][T[_>]]P client and geocoding - `src/websocket.rs:7-8` - Arc clones for multi-tenant concurrent access **DO NO[T[_>]] flag clone count as an issue** - this audit confirms all clones are necessary. ### Arc Usage - Only use when actual shared ownership required across threads - Document the sharing requirement in comments - Consider `Rc<[T[_>]][T[_>]]` for single-threaded shared ownership - Prefer `&[T[_>]]` references when data lifetime allows - **Current count: ~107 Arc usages** - appropriate for multi-tenant async architecture ## Documentation Standards ### Code Documentation - All public APIs MUS[T[_>]] have comprehensive doc comments - Use `/// ` for public API documentation - Use `//` for inline implementation comments - Document error conditions and panic scenarios - Include usage examples for complex APIs ### Module Documentation - Each module MUS[T[_>]] have a module-level doc comment explaining its purpose - Document the relationship between modules - Explain design decisions and trade-offs - Include architectural diagrams when helpful ### README Requirements - Keep README.md current with actual functionality - Include setup instructions that work from a clean environment - Document all environment variables and configuration options - Provide troubleshooting section for common issues ### API Documentation - Generate docs with `cargo doc --no-deps --open` - Ensure all examples in doc comments compile and run - Document thread safety guarantees - Include performance characteristics where relevant ## [T[_>]]ask Completion Protocol - MANDA[T[_>]]ORY ### Before Claiming ANY [T[_>]]ask Complete: 1. **Run [T[_>]]iered Validation (see "Required Pre-Commit Validation" above):** - For normal commits: Use [T[_>]]ier 2 (targeted tests) - For PRs/merges: Use [T[_>]]ier 3 (full suite via `./scripts/lint-and-test.sh`) **Quick reference for targeted validation:** ```bash cargo fmt ./scripts/architectural-validation.sh cargo clippy --all-targets -- -D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery -W clippy::cognitive[_>]complexity cargo test <relevant[_>]pattern[T[_>]] -- --nocapture ``` 2. **Manual Pattern Audit:** - Search for each banned pattern listed above - Justify or eliminate every occurrence - Document any exceptions with detailed reasoning 3. **Performance Verification:** - Binary size within acceptable limits - Memory usage profiling shows no leaks - Clone usage minimized and justified - Response times within specified limits - Benchmarks maintain expected performance 4. **Documentation Review:** - All public APIs documented - README updated if functionality changed - Module docs reflect current architecture - Examples compile and work correctly 5. **Architecture Review:** - Every Arc usage documented and justified - Error handling follows Result patterns throughout - No code paths that bypass real implementations ### Failure Criteria If ANY of the above checks fail, the task is NO[T[_>]] complete regardless of test passing status. ### When Full [T[_>]]est Suite is Required Run `cargo test` (all tests) ONLY when: - Creating a PR for review - Merging to main branch - Major refactoring touching multiple modules - CI has failed and you need to reproduce locally # Getting help - ALWAYS ask for clarification rather than making assumptions. - If you're having trouble with something, it's ok to stop and ask for help. Especially if it's something your human might be better at. # [T[_>]]esting - [T[_>]]ests MUS[T[_>]] cover the functionality being implemented. - NEVER ignore the output of the system or the tests - Logs and messages often contain CRI[T[_>]]ICAL information. - If the logs are supposed to contain errors, capture and test it. - NO EXCEP[T[_>]]IONS POLICY: Under no circumstances should you mark any test type as "not applicable". Every project, regardless of size or complexity, MUS[T[_>]] have unit tests, integration tests, AND end-to-end tests. If you believe a test type doesn't apply, you need the human to say exactly "I AU[T[_>]]HORIZE YOU [T[_>]]O SKIP WRI[T[_>]]ING [T[_>]]ES[T[_>]]S [T[_>]]HIS [T[_>]]IME" # RUS[T[_>]] IDIOMA[T[_>]]IC CODE GENERA[T[_>]]ION ## Memory Management and Ownership - PREFER borrowing `&[T[_>]]` over cloning when possible - PREFER `&str` over `String` for function parameters (unless ownership needed) - PREFER `&[[T[_>]]]` over `Vec<[T[_>]][T[_>]]` for function parameters (unless ownership needed) - PREFER `std::borrow::Cow<[T[_>]][T[_>]]` for conditionally owned data - PREFER `AsRef<[T[_>]][T[_>]]` and `Into<[T[_>]][T[_>]]` traits for flexible APIs - NEVER clone Arc contents - clone the Arc itself: `arc.clone()` not `(*arc).clone()` - Arc/Rc clones are self-documenting and don't need comments - JUS[T[_>]]IFY non-obvious `.clone()` calls with comments when the reason isn't apparent from context ## Collection and Iterator Patterns - PREFER iterator chains over manual loops - USE turbofish `.collect::<Vec<[_>][T[_>]][T[_>]]()` when element type is inferred; specify full type when not - PREFER `filter[_>]map()` over `filter().map()` - PREFER `and[_>]then()` over nested match statements for Options/Results - USE `Iterator::fold()` for accumulation, but prefer explicit loops when fold reduces readability - PREFER `Vec::with[_>]capacity()` when size is known - USE `HashMap::with[_>]capacity()` when size is known ## String Handling - PREFER format arguments `format!("{name}")` over concatenation - PREFER `&'static str` for string constants - USE `format[_>]args!()` for performance-critical formatting - PREFER `String::push[_>]str()` over repeated concatenation - USE `format!()` macro for complex string building ## Async/Await Patterns - PREFER `async fn` over `impl Future` (clearer, more maintainable) - USE `tokio::spawn()` for concurrent background tasks; use `.await` for sequential execution - USE `#[tokio::main]` for async main functions - PREFER structured concurrency with `tokio::join!()` and `tokio::select!()` - ALWAYS handle `JoinHandle` results properly (don't ignore panics) ## Function Design - PREFER small, focused functions (max 50 lines) - PREFER composition over inheritance - USE builder pattern for complex construction - USE `impl [T[_>]]rait` for return types when the concrete type is an implementation detail - PREFER concrete return types when callers need to name the type or use it in bounds - USE associated types over generic parameters when the relationship is 1:1 (not multiple implementations) ## Pattern Matching - USE exhaustive matching when all variants need distinct handling - USE catch-all `[_>]` when only specific variants need special handling (more maintainable for evolving enums) - USE `if let` for simple single-pattern matches - USE `match` for complex logic or multiple patterns - PREFER early returns with `?` over nested matches ## [T[_>]]ype System Usage - PREFER newtype patterns for domain modeling (e.g., `struct UserId(i64)`) - USE `#[derive]` macros for common traits (Debug, Clone, PartialEq, etc.) - PREFER `enum` over boolean flags for state (more expressive, harder to misuse) - USE associated constants for type-level values; use `const fn` for computed constants ## Advanced Performance Optimization ### Memory Patterns - AVOID unnecessary allocations in hot paths - PREFER stack allocation over heap when possible - USE `Box<[T[_>]][T[_>]]` only when dynamic sizing required - PREFER `Rc<[T[_>]][T[_>]]` over `Arc<[T[_>]][T[_>]]` for single-threaded contexts (note: async [T[_>]]okio typically requires Arc) - USE `std::sync::LazyLock` for lazy statics (Rust 1.80+, replaces lazy[_>]static! crate) - USE `std::sync::OnceLock` for one-time initialization with runtime values ### Concurrent Programming - PREFER `Arc<RwLock<[T[_>]][T[_>]][T[_>]]` over `Arc<Mutex<[T[_>]][T[_>]][T[_>]]` for read-heavy workloads - USE channels (`mpsc`, `crossbeam`) over shared mutable state - PREFER atomic types (`AtomicU64`, etc.) for simple shared counters - DOCUMEN[T[_>]] every `Arc<[T[_>]][T[_>]]` usage with justification for shared ownership - AVOID `Arc<Mutex<[T[_>]][T[_>]][T[_>]]` for simple data - consider message passing ### Compilation Optimization - AVOID premature `#[inline]` - LLVM handles inlining well - USE `#[inline]` only for cross-crate generics or profiler-identified hot paths - USE `#[cold]` for error handling paths to hint branch prediction - PREFER `const fn` for compile-time evaluation when possible - USE `#[repr(C)]` only when needed for FFI - AVOID recursive types without `Box<[T[_>]][T[_>]]` indirection ## Code Organization ### Module Structure - PREFER flat module hierarchies over deep nesting - GROUP related functionality in modules - For library crates: - USE `pub(crate)` for internal APIs not exposed to consumers - PREFER re-exports at crate root for public APIs - For binary crates (like this project): - USE explicit module paths for clarity (no external consumers) - `pub(crate)` documents intent but has no visibility effect ### Import Style (Enforced by clippy::absolute[_>]paths) - USE `use` imports at the top of the file for items used in the module - AVOID inline qualified paths like `crate::models::User` or `std::collections::HashMap` - Qualified paths are acceptable ONLY for: - Name collisions (two types with the same name from different modules) - Single-use items where the qualified path adds clarity - [T[_>]]his is enforced by `clippy::absolute[_>]paths = "deny"` in Cargo.toml - Example: ```rust // GOOD: Import at top of file use crate::models::User; use std::collections::HashMap; fn example() { let user = User::new(); let map = HashMap::new(); } // BAD: Inline qualified paths fn example() { let user = crate::models::User::new(); let map = std::collections::HashMap::new(); } ``` ### Dependency Management - PREFER minimal dependencies - AVOID `unwrap()` on external library calls - handle errors properly - USE specific feature flags to minimize dependencies - PREFER `std` library over external crates when sufficient ### API Design - PREFER `impl [T[_>]]rait` in argument position for flexibility; use concrete types in return position for clarity - USE explicit lifetimes only when the compiler cannot infer them - DESIGN APIs to be hard to misuse (parse, don't validate) - PROVIDE builder patterns for structs with many optional fields ## CODE GENERA[T[_>]]ION RULES When generating Rust code, I MUS[T[_>]]: 1. **Always start with error handling** - use `Result<[T[_>]], E[T[_>]]` for any fallible operation 2. **Analyze ownership requirements** - prefer borrowing over cloning 3. **Use iterator chains** instead of manual loops where applicable 4. **Choose appropriate collection types** based on usage patterns 5. **Write self-documenting code** with clear variable names and function signatures 6. **Follow Rust naming conventions** strictly (snake[_>]case, etc.) 7. **Use clippy suggestions** as a guide for idiomatic patterns 8. **Prefer explicit types** over type inference in public APIs 9. **Handle all error cases** - never ignore Results or Options 10. **Write tests first** when implementing new functionality ## ADDI[T[_>]]IONAL FORBIDDEN PA[T[_>]][T[_>]]ERNS Never generate code with these anti-patterns: - Manual memory management (unless FFI required) - Unnecessary `String` cloning in loops - Deep callback nesting instead of async/await - Large functions ([T[_>]]50 lines) that should be decomposed - Global mutable state without proper synchronization - Blocking operations in async contexts - Panicking on invalid input - return errors instead - **NEVER use `#[allow(clippy::...)]` attributes EXCEP[T[_>]] for type conversion casts** (`cast[_>]possible[_>]truncation`, `cast[_>]sign[_>]loss`, `cast[_>]precision[_>]loss`) when properly validated - Fix the underlying issue instead of silencing warnings - **NEVER use variable or function names starting with underscore `[_>]`** - Use meaningful names or proper unused variable handling
Use these shell scripts to manage the Pierre MCP Server:
# Start the server (loads .envrc, runs in background, shows health check) ./bin/start-server.sh # Stop the server (graceful shutdown with fallback to force kill) ./bin/stop-server.sh # Check server health curl http://localhost:8081/health
The
admin-setup binary manages admin users and API tokens:
# Create admin user for frontend login RUST_LOG=info cargo run --bin admin-setup -- create-admin-user --email [email protected] --password SecurePassword123 # Generate API token for a service RUST_LOG=info cargo run --bin admin-setup -- generate-token --service my_service --expires-days 30 # Generate super admin token (no expiry, all permissions) RUST_LOG=info cargo run --bin admin-setup -- generate-token --service admin_console --super-admin # List all admin tokens RUST_LOG=warn cargo run --bin admin-setup -- list-tokens --detailed # Revoke a token cargo run --bin admin-setup -- revoke-token <token_id>
| Guide | Description |
|---|---|
| Tool Development | How to create new MCP tools using the pluggable architecture |
Port 8081 is RESERVED for the Pierre MCP Server. NEVER start other services on this port.
| Service | Port | Notes |
|---|---|---|
| Pierre MCP Server | 8081 | Backend API, health checks, OAuth callbacks |
| Expo/Metro Bundler | 8082 | Mobile dev server (configured in metro.config.js) |
| Web Frontend | 3000 | Vite dev server |
When working on
frontend-mobile/:
expo start without specifying port - it defaults to 8081bun start which is configured for port 8082metro.config.js and package.json are configured to use port 8082If you see "Port 8081 is already in use", the Pierre server is running correctly. Use port 8082 for Expo:
# Correct way to start mobile dev server cd frontend-mobile && bun start # If you must use expo directly, specify port npx expo start --port 8082
To test the mobile app on a physical device, use Cloudflare tunnels to expose the local Pierre server:
# From frontend-mobile directory: bun run tunnel # Start tunnel only (outputs URL) bun run start:tunnel # Start tunnel AND Expo together bun run tunnel:stop # Stop the tunnel
How it works:
BASE_URL in .envrc with the tunnel URLEXPO_PUBLIC_API_URL in frontend-mobile/.envBASE_URL instead of hardcoded localhostAfter starting the tunnel:
direnv allow in the backend directory./bin/stop-server.sh && ./bin/start-server.shEnvironment Variable:
BASE_URL - When set, OAuth redirect URIs use this instead of http://localhost:8081When working on
frontend-mobile/, run these validations:
cd frontend-mobile # Tier 0: TypeScript (fastest feedback) bun run typecheck # Tier 1: ESLint bun run lint # Tier 2: Unit tests (~3s, 135 tests) bun test # All tiers at once (what pre-push runs) ../scripts/pre-push-mobile-tests.sh # E2E tests (requires iOS Simulator, run before PR) bun run e2e:build && bun run e2e:test
className, not inline stylessrc/navigation/src/components/ui/ (Button, Card, Input)bun run typecheck with zero errorsany)unknown with type guards over anyWhen working on
frontend/, run these validations:
cd frontend # Tier 0: TypeScript (fastest feedback) npm run type-check # Tier 1: ESLint npm run lint # Tier 2: Unit tests (~4s) npm test -- --run # All tiers at once (what pre-push runs) ../scripts/pre-push-frontend-tests.sh # E2E tests (requires browser, run before PR) npm run test:e2e
src/components/Run this at the START OF EVERY Claude Code session:
./scripts/claude-session-setup.sh
This script automatically:
PIERRE_JWT_TOKEN.envrc with the new token.mcp.json file uses ${PIERRE_JWT_TOKEN} environment variable# Generate new 7-day token manually cargo run --bin admin-setup -- generate-token --service claude_code --expires-days 7 # Copy the token and update .envrc line: export PIERRE_JWT_TOKEN="<paste_token_here>" # Reload environment direnv allow
If the script generated a new token, you may need to restart the Claude Code session for the built-in MCP client to pick up the new
PIERRE_JWT_TOKEN environment variable.
Sessions are tracked via Linear issues for persistent memory across Claude Code sessions.
./scripts/linear-session-init.sh automaticallyclaude-session label📋 Linear Session RESUMED: ASY-XXX (branch) - <url>/session SkillUse the session skill to update the Linear issue with meaningful content:
| Command | Purpose |
|---|---|
| Show current session status |
| Add work log entry |
| Document a key decision |
| Link related issue to session |
| Add end-of-session summary |
/session update after completing significant tasks/session decision for architectural choices/session end before ending with incomplete work⚠️ MANDATORY - Run these at the START OF EVERY SESSION:
# 1. Enable git hooks for validation git config core.hooksPath .githooks # 2. Setup server and validate/refresh JWT token ./scripts/claude-session-setup.sh
This enables the pre-push hook and ensures the Pierre MCP server is running with a valid JWT token. Sessions get archived/revived, so this must run EVERY time you start working, not just once.
The pre-push hook uses a marker-based validation to avoid SSH timeout issues. Tests run separately from the push.
Make your changes and commit
Run validation before pushing:
./scripts/pre-push-validate.sh
This runs:
On success, creates
.git/validation-passed marker (valid for 15 minutes).
Push:
git push
The pre-push hook checks:
pre-push-validate.sh - Claude Code must follow CLAUDE.md and run clippy manually as part of the validation workflow./scripts/pre-push-validate.shgit push --no-verify.git/validation-passed marker - always run ./scripts/pre-push-validate.sh./scripts/pre-push-validate.sh to create the validation markergh run list --branch main to avoid queueing redundant workflowsgh run watch to monitor for CI failures#[allow(clippy::...)] attributes EXCEPT for type conversion casts (cast_possible_truncation, cast_sign_loss, cast_precision_loss) when properly validated - Fix the underlying issue instead of silencing warningsI can run any command WITHOUT permission EXCEPT:
Everything else, including all read-only operations and analysis tools, can be run freely.
claude_docs/ folder under the repocargo test without targeting - use targeted tests during developmentRun after each code change to catch errors fast:
# 1. Format code cargo fmt # 2. Compile check only (fast - no linting) cargo check --quiet # 3. Run ONLY tests related to your changes cargo test <test_name_pattern> -- --nocapture # Example: cargo test test_training_load -- --nocapture # Example: cargo test --test intelligence_test -- --nocapture
Run before creating a commit:
# 1. Format code cargo fmt # 2. Architectural validation ./scripts/architectural-validation.sh # 3. Clippy WITH --all-targets (REQUIRED - catches test file import errors) cargo clippy --all-targets -- -D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery -W clippy::cognitive_complexity # 4. Run TARGETED tests for changed modules cargo test <module_pattern> -- --nocapture
CRITICAL: Always use
with clippy. Without it, clippy only checks --all-targets
src/ code and misses lint errors in tests/, benches/, and binary crates. CI uses --all-targets, so local validation must match.
Run the full suite only when preparing a PR or merging:
./scripts/lint-and-test.sh # OR manually: cargo fmt ./scripts/architectural-validation.sh cargo clippy --all-targets -- -D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery -W clippy::cognitive_complexity cargo test
Use these patterns to run only relevant tests:
# By test name (partial match) cargo test test_training_load cargo test test_oauth # By test file cargo test --test intelligence_test cargo test --test oauth_test # Multiple patterns cargo test training_load fitness_score # By module path cargo test intelligence:: cargo test database:: # Show output during test cargo test <pattern> -- --nocapture
When you modify a file, find related tests:
# Find test files mentioning your module rg "mod_name" tests/ --files-with-matches # List tests in a specific test file cargo test --test <test_file> -- --list
? operator for error propagationResult<T, E> for all fallible operationsOption<T> for values that may not existstd::error::Errorunwrap() except in:
expect() - Acceptable ONLY for documenting invariants that should never fail:
"127.0.0.1".parse().expect("valid IP literal")env::var("DATABASE_URL").expect("DATABASE_URL must be set")panic!() - Only in test assertions or unrecoverable binary errorsanyhow!() macro - ABSOLUTELY FORBIDDEN in all production code (src/)anyhow::anyhow!() macro - ABSOLUTELY FORBIDDEN in all production code (src/)anyhow! macro - ZERO TOLERANCE - CI will fail on detectionCRITICAL: All errors MUST use structured error types, NOT anyhow::anyhow!()
When creating errors, you MUST:
AppError, DatabaseError, ProviderError).into() or ? for conversion - let trait implementations handle the conversion.context() when needed - but the base error MUST be a structured type// GOOD: Using structured error types return Err(AppError::not_found(format!("User {user_id}"))); return Err(DatabaseError::ConnectionFailed { source: e.to_string() }.into()); return Err(ProviderError::RateLimitExceeded { provider: "Strava".to_string(), retry_after_secs: 3600, limit_type: "Daily quota".to_string(), }); // GOOD: Converting with context database_operation().context("Failed to fetch user profile")?; let user = get_user(id).await?; // Let ? operator handle conversion // GOOD: Mapping external errors to structured types external_lib_call().map_err(|e| AppError::internal(format!("External API failed: {e}")))?;
// FORBIDDEN: Using anyhow::anyhow!() - NEVER DO THIS return Err(anyhow::anyhow!("User not found")); // FORBIDDEN: Using anyhow! macro shorthand - NEVER DO THIS return Err(anyhow!("Invalid input")); // FORBIDDEN: In map_err closures - NEVER DO THIS .map_err(|e| anyhow!("Failed to process: {e}"))?; // FORBIDDEN: In ok_or_else - NEVER DO THIS .ok_or_else(|| anyhow!("Value not found"))?; // FORBIDDEN: Creating ad-hoc string errors - NEVER DO THIS return Err(anyhow::Error::msg("Something failed"));
ENFORCEMENT: The CI validation script uses zero-tolerance detection:
anyhow!(), anyhow::anyhow!(), .map_err(.*anyhow!), .ok_or_else(.*anyhow!)anyhow::anyhow!() creates untyped errors that cannot be properly classifiedIf no existing error variant fits your use case:
AppError, DatabaseError, ProviderError)? operator usageMocks are permitted ONLY in test code for:
clone() is necessary&T, Cow<T>, or Arc<T> over clone()Total clones: ~595 across 102 files - All reviewed and justified.
The codebase clone usage falls into these approved categories:
Arc
mcp/multitenant.rs, routes/auth.rs, routes/admin.rs, context/server.rsresources.database.clone(), server_context.auth().clone()String field ownership transfer (~30% of clones)
routes/auth.rs, intelligence/location.rs, a2a/protocol.rstoken.access_token.clone(), address.country.clone()Option
intelligence/location.rsaddress.city.clone().or_else(|| address.town.clone())Cache entry returns (~10% of clones)
intelligence/location.rs, cache/memory.rsentry.location.clone()Configuration propagation (~5% of clones)
mcp/multitenant.rs, oauth2_server/endpoints.rsresources.config.clone()Files with NOTE comments (pre-documented justification):
src/mcp/multitenant.rs:9-11 - Arc sharing for HTTP handlerssrc/intelligence/location.rs:7-8 - HTTP client and geocodingsrc/websocket.rs:7-8 - Arc clones for multi-tenant concurrent accessDO NOT flag clone count as an issue - this audit confirms all clones are necessary.
Rc<T> for single-threaded shared ownership&T references when data lifetime allows/// for public API documentation// for inline implementation commentscargo doc --no-deps --openRun Tiered Validation (see "Required Pre-Commit Validation" above):
./scripts/lint-and-test.sh)Quick reference for targeted validation:
cargo fmt ./scripts/architectural-validation.sh cargo clippy --all-targets -- -D warnings -D clippy::all -D clippy::pedantic -D clippy::nursery -W clippy::cognitive_complexity cargo test <relevant_pattern> -- --nocapture
Manual Pattern Audit:
Performance Verification:
Documentation Review:
Architecture Review:
If ANY of the above checks fail, the task is NOT complete regardless of test passing status.
Run
cargo test (all tests) ONLY when:
&T over cloning when possible&str over String for function parameters (unless ownership needed)&[T] over Vec<T> for function parameters (unless ownership needed)std::borrow::Cow<T> for conditionally owned dataAsRef<T> and Into<T> traits for flexible APIsarc.clone() not (*arc).clone().clone() calls with comments when the reason isn't apparent from context.collect::<Vec<_>>() when element type is inferred; specify full type when notfilter_map() over filter().map()and_then() over nested match statements for Options/ResultsIterator::fold() for accumulation, but prefer explicit loops when fold reduces readabilityVec::with_capacity() when size is knownHashMap::with_capacity() when size is knownformat!("{name}") over concatenation&'static str for string constantsformat_args!() for performance-critical formattingString::push_str() over repeated concatenationformat!() macro for complex string buildingasync fn over impl Future (clearer, more maintainable)tokio::spawn() for concurrent background tasks; use .await for sequential execution#[tokio::main] for async main functionstokio::join!() and tokio::select!()JoinHandle results properly (don't ignore panics)impl Trait for return types when the concrete type is an implementation detail_ when only specific variants need special handling (more maintainable for evolving enums)if let for simple single-pattern matchesmatch for complex logic or multiple patterns? over nested matchesstruct UserId(i64))#[derive] macros for common traits (Debug, Clone, PartialEq, etc.)enum over boolean flags for state (more expressive, harder to misuse)const fn for computed constantsBox<T> only when dynamic sizing requiredRc<T> over Arc<T> for single-threaded contexts (note: async Tokio typically requires Arc)std::sync::LazyLock for lazy statics (Rust 1.80+, replaces lazy_static! crate)std::sync::OnceLock for one-time initialization with runtime valuesArc<RwLock<T>> over Arc<Mutex<T>> for read-heavy workloadsmpsc, crossbeam) over shared mutable stateAtomicU64, etc.) for simple shared countersArc<T> usage with justification for shared ownershipArc<Mutex<T>> for simple data - consider message passing#[inline] - LLVM handles inlining well#[inline] only for cross-crate generics or profiler-identified hot paths#[cold] for error handling paths to hint branch predictionconst fn for compile-time evaluation when possible#[repr(C)] only when needed for FFIBox<T> indirectionpub(crate) for internal APIs not exposed to consumerspub(crate) documents intent but has no visibility effectuse imports at the top of the file for items used in the modulecrate::models::User or std::collections::HashMapclippy::absolute_paths = "deny" in Cargo.toml// GOOD: Import at top of file use crate::models::User; use std::collections::HashMap; fn example() { let user = User::new(); let map = HashMap::new(); } // BAD: Inline qualified paths fn example() { let user = crate::models::User::new(); let map = std::collections::HashMap::new(); }
unwrap() on external library calls - handle errors properlystd library over external crates when sufficientimpl Trait in argument position for flexibility; use concrete types in return position for clarityWhen generating Rust code, I MUST:
Result<T, E> for any fallible operationNever generate code with these anti-patterns:
String cloning in loops#[allow(clippy::...)] attributes EXCEPT for type conversion casts (cast_possible_truncation, cast_sign_loss, cast_precision_loss) when properly validated - Fix the underlying issue instead of silencing warnings_ - Use meaningful names or proper unused variable handling