Files
optimclaw/.claude/rules/review-discipline.md
bcbdc273a5 Restructure CLAUDE.md into modular rules + add pr-shepherd command (#750)
* refactor: restructure CLAUDE.md into modular rules and add pr-shepherd command

Trim CLAUDE.md from 710 lines to 92 by moving detailed guidance into
path-scoped `.claude/rules/` files that load on demand. Add a new
`/pr-shepherd` command that consolidates the full PR lifecycle
(review, fix, quality gate, CI fix loop, merge) into one workflow.

Changes:
- CLAUDE.md: keep only essentials (build commands, code style, architecture,
  module specs, config reference, debugging)
- .claude/rules/review-discipline.md: 15+ review rules, scoped to src/**/*.rs
- .claude/rules/database.md: dual-backend rules with SQL dialect translation
  table, scoped to src/db/** and migrations/**
- .claude/rules/safety-and-sandbox.md: safety layer and sandbox rules, scoped
  to src/safety/**, src/sandbox/**, src/secrets/**
- .claude/rules/testing.md: test tiers and patterns, scoped to src/** and tests/**
- .claude/rules/tools.md: tool architecture and implementation pattern, scoped
  to src/tools/** and tools-src/**
- .claude/commands/pr-shepherd.md: 7-phase PR lifecycle command that subsumes
  review-pr, respond-pr, ship, and manual CI fix loops

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: address review feedback on CLAUDE.md restructure

- Restore project structure tree in CLAUDE.md (zmanian blocking)
- Create .claude/rules/skills.md with trust model, SKILL.md format,
  selection pipeline, and skill tools (zmanian blocking)
- Restore configuration section with key env vars (zmanian medium)
- Restore "Adding a New Channel" guide (zmanian medium)
- Add heartbeat mention to Workspace & Memory section (zmanian low)
- Fix pr-shepherd: replace `git add -A` with specific file staging (zmanian)
- Fix pr-shepherd: ask user for merge strategy instead of hardcoding --squash (zmanian)
- Fix pr-shepherd: replace `--watch` with polling + 10min timeout (zmanian)
- Fix testing.md: "skipped if DB is unreachable" not "expected to fail" (Copilot)

[skip-regression-check]

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: address review comments on PR #750

- Narrow `crate::` import rule: `super::` is fine in tests and intra-module refs
- Fix capabilities file naming: `<name>.capabilities.json` sidecar, not bare `capabilities.json`
- Update mechanical verification checklist to match narrowed import rule

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* refactor: move Bedrock docs from CLAUDE.md to src/llm/CLAUDE.md

Bedrock provider details (auth, config, feature flag) belong in the
LLM module spec, not the top-level guide. Added file map entry,
provider table row, and dedicated section in src/llm/CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* refactor: move env var config block out of CLAUDE.md

Replace 20-line config block with one-liner pointing to .env.example
and src/llm/CLAUDE.md. Config details are only needed during deployment,
not everyday coding.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: use gh pr checkout for fork-safe PR checkout in pr-shepherd

Replaces git fetch/checkout with gh pr checkout {number} which
handles both same-repo and fork-based PRs automatically.

Co-Authored-By: Claude Opus 4.6 <[email protected]>

* fix: address Copilot review round 5 on PR #750

- Add gh pr list and gh pr checkout to pr-shepherd allowed-tools
- Align crate:: import rule in pr-shepherd with updated CLAUDE.md guidance
- Fix vector type in database.md: BLOB (flexible dims), not F32_BLOB(1536)
- Update MCP limitation: stdio/HTTP/Unix transports exist, no streaming

Co-Authored-By: Claude Opus 4.6 <[email protected]>

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
2026-03-09 23:19:25 +00:00

3.9 KiB

paths
paths
src/**/*.rs

Review & Fix Discipline

Hard-won lessons from code review -- follow these when fixing bugs or addressing review feedback.

Fix the pattern, not just the instance: When a reviewer flags a bug (e.g., TOCTOU race in INSERT + SELECT-back), search the entire codebase for all instances of that same pattern. A fix in SecretsStore::create() that doesn't also fix WasmToolStore::store() is half a fix.

Propagate architectural fixes to satellite types: If a core type changes its concurrency model (e.g., LibSqlBackend switches to connection-per-operation), every type that was handed a resource from the old model must also be updated. Grep for the old type across the codebase.

Schema translation is more than DDL: When translating a database schema between backends (PostgreSQL to libSQL, etc.), check for:

  • Indexes -- diff CREATE INDEX statements between the two schemas
  • Seed data -- check for INSERT INTO in migrations (e.g., leak_detection_patterns)
  • Semantic differences -- document where SQL functions behave differently (e.g., json_patch vs jsonb_set)

Feature flag testing: When adding feature-gated code, test compilation with each feature in isolation:

cargo check                                          # default features
cargo check --no-default-features --features libsql  # libsql only
cargo check --all-features                           # all features

Regression test with every fix: Every bug fix must include a test that would have caught the bug. Add a #[test] or #[tokio::test] that reproduces the original failure. Exempt: changes limited to src/channels/web/static/ or .md files. Use [skip-regression-check] in commit message or PR label if genuinely not feasible. The commit-msg hook and CI workflow enforce this automatically.

Zero clippy warnings policy: Fix ALL clippy warnings before committing, including pre-existing ones in files you didn't change. Never leave warnings behind.

Transaction safety: Multi-step database operations (INSERT+INSERT, UPDATE+DELETE, read-then-write) MUST be wrapped in a transaction. Never assume sequential calls are atomic. This applies to both postgres and libsql backends.

UTF-8 string safety: Never use byte-index slicing (&s[..n]) on user-supplied or external strings -- it panics on multi-byte characters. Use is_char_boundary() or char_indices(). Grep for [.. in changed files.

Case-insensitive comparisons: When comparing user-supplied strings (file paths, media types, extension names), normalize to lowercase with .to_ascii_lowercase(). Path comparisons must be case-insensitive on macOS/Windows.

Decorator/wrapper trait delegation: When adding a new method to LlmProvider (or any trait with decorator wrappers), update ALL wrapper types to delegate. Grep for impl LlmProvider for to find all implementations. Test through the full provider chain.

Sensitive data in logs & events: Tool parameters and outputs MUST be redacted before logging or broadcasting via SSE/WebSocket. Use redact_params() before any tracing::info!, JobEvent, or SSE emission that includes tool call data.

Test temporary files: Use the tempfile crate. Never hardcode /tmp/... paths.

Trust boundaries in multi-process architecture: Data from worker containers is untrusted. The orchestrator MUST validate: tool domain, nesting depth (server-side tracking), and parameter sensitivity.

Mechanical verification before committing:

  • cargo clippy --all --benches --tests --examples --all-features -- zero warnings
  • grep -rnE '\.unwrap\(|\.expect\(' <files> -- no panics in production
  • grep -rn 'super::' <files> -- prefer crate:: for cross-module imports (super:: OK in tests/intra-module)
  • If you fixed a pattern bug, grep for other instances across src/
  • Run scripts/pre-commit-safety.sh to catch UTF-8, case-sensitivity, hardcoded /tmp, and logging issues