Skip to content

docs: improve CLAUDE.md clarity and add project rules#95

Merged
aryeko merged 3 commits intomainfrom
docs/improve-claude-md
Feb 22, 2026
Merged

docs: improve CLAUDE.md clarity and add project rules#95
aryeko merged 3 commits intomainfrom
docs/improve-claude-md

Conversation

@aryeko
Copy link
Owner

@aryeko aryeko commented Feb 22, 2026

Summary

  • Add prominent Before Every Commit section with poetry run poe check (lint + format-check + typecheck + non-E2E tests)
  • Standardize all task commands to use poetry run poe consistently
  • Add Key Files quick-reference table for faster orientation
  • Move .claude/rules/*.md files into .claude/rules/ so Claude Code auto-loads them
  • Remove boilerplate intro line; clarify generated GraphQL client anti-pattern wording
  • Address CodeRabbit review: fix poe gen-gql prefix, replace black/isort with ruff, clarify bandit is optional, fix Python-specific hyphenation
  • Move project-level rules to ~/.claude/rules/python/ — now reusable across all Python projects

Test plan

  • Run poetry run poe check to verify it passes
  • Confirm ~/.claude/rules/python/ files load in Claude Code when working with .py files
  • Run poetry run poe docs-links to verify no broken internal links

🤖 Generated with Claude Code

- Remove boilerplate intro line
- Add prominent "Before Every Commit" section with poe check
- Standardize all commands to use `poetry run poe`
- Add Key Files quick-reference table
- Add note about .claude/rules/ auto-loaded guidelines
- Clarify generated GraphQL client anti-pattern wording
- Move .claude/*.md files into .claude/rules/ for auto-loading
@coderabbitai
Copy link

coderabbitai bot commented Feb 22, 2026

📝 Walkthrough

Walkthrough

Adds five new Python-specific rule documents under .claude/rules/ (coding style, hooks, patterns, security, testing) and updates CLAUDE.md to standardize command invocations to poetry run poe and add key-files/workflow notes.

Changes

Cohort / File(s) Summary
Python Rules docs
​.claude/rules/coding-style.md, ​.claude/rules/hooks.md, ​.claude/rules/patterns.md, ​.claude/rules/security.md, ​.claude/rules/testing.md
Adds five Python-focused rule files: coding-style (PEP 8, required type annotations, black/isort/ruff, immutable examples), hooks (post-tool hooks, path globs, print() warning → use logging), patterns (Protocol, dataclass DTO, context managers/generators guidance), security (dotenv secret handling, bandit scanning, Django note), testing (pytest usage, test organization, coverage command).
Documentation / Workflow
CLAUDE.md
Replaces direct task examples with poetry run poe <task> variants across documentation, adds a "Key Files" section, updates GraphQL generation and docs commands to use the poetry run prefix.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly related PRs

Poem

🐰 I hopped through rules and left a note,
Of blackened lines and types that float,
With hooks that tidy, tests that sing,
Poetry-run makes tasks take wing,
A tiny hop for code — rejoice and vote!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main changes: improving CLAUDE.md clarity and adding project rules files to .claude/rules/.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description check ✅ Passed The PR description covers the main changes (Claude.md improvements and .claude/rules files) and includes a test plan with verification steps.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch docs/improve-claude-md

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Feb 22, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
CLAUDE.md (1)

78-78: ⚠️ Potential issue | 🟡 Minor

poe gen-gql still missing poetry run prefix

Line 78 is the only remaining spot in the file that uses the bare poe gen-gql command. The Anti-Patterns section on Line 88 already uses poetry run poe gen-gql correctly. This inconsistency partially defeats the PR's standardization goal.

✏️ Proposed fix
-- **Generated code**: `src/planpilot/core/providers/github/github_gql/` is excluded from mypy and coverage. Regenerate with `poe gen-gql`.
+- **Generated code**: `src/planpilot/core/providers/github/github_gql/` is excluded from mypy and coverage. Regenerate with `poetry run poe gen-gql`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@CLAUDE.md` at line 78, Replace the bare command string "poe gen-gql" with the
standardized "poetry run poe gen-gql" in the CLAUDE.md occurrence that
references regenerating src/planpilot/core/providers/github/github_gql/ so the
file matches the Anti-Patterns section's usage; update the single remaining "poe
gen-gql" instance to "poetry run poe gen-gql".
🧹 Nitpick comments (3)
.claude/rules/hooks.md (1)

12-15: Consider providing a concrete ~/.claude/settings.json snippet

The guidance says to "configure in ~/.claude/settings.json" but omits a sample. Without an example, developers need to separately research Claude Code's hook configuration format. A minimal JSON snippet would make this immediately actionable.

Additionally, Line 14 lists black/ruff for formatting; since the project standardizes on ruff format alone, preferring ruff in the example avoids ambiguity.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/hooks.md around lines 12 - 15, Add a concrete example JSON
snippet to ~/.claude/settings.json that replaces the ambiguous "black/ruff" text
with the project-preferred "ruff" and shows the exact hook entries for Python
files: include a "hooks" object with a pattern for "*.py" and commands for
formatting using "ruff format" and for type checking using the chosen tool
("mypy" or "pyright"), so reviewers can copy-paste the minimal working
configuration rather than researching the hook schema.
.claude/rules/coding-style.md (1)

19-32: from typing import NamedTuple import appears mid-block

The single code block interleaves a second import (from typing import NamedTuple) after a class definition. While the intent is clear, it reads as non-idiomatic Python where all imports live at the top of a file. Splitting into two labeled code blocks would eliminate any ambiguity.

✏️ Suggested fix
-```python
-from dataclasses import dataclass
-
-@dataclass(frozen=True)
-class User:
-    name: str
-    email: str
-
-from typing import NamedTuple
-
-class Point(NamedTuple):
-    x: float
-    y: float
-```
+**Frozen dataclass:**
+```python
+from dataclasses import dataclass
+
+@dataclass(frozen=True)
+class User:
+    name: str
+    email: str
+```
+
+**NamedTuple:**
+```python
+from typing import NamedTuple
+
+class Point(NamedTuple):
+    x: float
+    y: float
+```
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/coding-style.md around lines 19 - 32, The code block places
"from typing import NamedTuple" after the User dataclass, which is
non-idiomatic; move all imports to the top or split into two labeled blocks so
imports precede definitions. Specifically, ensure "from dataclasses import
dataclass" is grouped with the User dataclass declaration (class User) and "from
typing import NamedTuple" is placed before the Point definition (class Point),
or separate them into two distinct code blocks labeled (e.g., "Frozen dataclass"
and "NamedTuple") so each import sits immediately above its related type
definition.
.claude/rules/security.md (1)

23-26: bandit is not in dependencies or the poe check pipeline

The guide instructs running bandit -r src/, but bandit is not declared in pyproject.toml and no poe task exists for it. The poe check pipeline currently runs: ["lint", "format-check", "typecheck", "test"].

Either add a poe security task for bandit and include it in the pipeline, or update the guidance to explicitly note this is an optional manual step that developers must set up separately.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/security.md around lines 23 - 26, The docs instruct running
bandit but the project doesn't declare bandit in pyproject.toml nor include it
in the poe "check" pipeline; either add a poe task (e.g., name it "security")
that runs "bandit -r src/" and include "security" in the poe "check" list, and
add bandit to the project's dev dependencies in pyproject.toml, or update
.claude/rules/security.md to state that running bandit is an optional manual
step and mention that a poe task is not provided by default; reference the
bandit command, the poe "check" pipeline, and pyproject.toml when making the
change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.claude/rules/coding-style.md:
- Around line 36-38: Replace the misleading tooling list that names "black" and
"isort" alongside "ruff" with a single accurate description stating that the
project uses "ruff format" for formatting and "ruff check" for linting and
import-sorting; specifically update the lines that mention **black** and
**isort** so they no longer appear and instead document **ruff format** and
**ruff check** (or similar phrasing) to reflect the actual setup and avoid
suggesting conflicting formatters.

In @.claude/rules/testing.md:
- Line 8: Update the compound adjective "Python specific content" to the
hyphenated form "Python-specific content" in this file (the line that currently
reads "This file extends [common/testing.md](../common/testing.md) with Python
specific content.") and make the identical change in the other four rule files
that use the same phrasing so all five files consistently use "Python-specific
content".
- Around line 27-34: Register the custom pytest marks "unit" and "integration"
to avoid PytestUnknownMarkWarning by adding them under the
[tool.pytest.ini_options] section in pyproject.toml; specifically add entries
for the markers list that document "unit" and "integration" (so tests that use
`@pytest.mark.unit` and `@pytest.mark.integration` are recognized).

In `@CLAUDE.md`:
- Line 5: Update the short banner description for the poe check command so it
includes "format-check" to match the detailed description; specifically modify
the text "Run `poetry run poe check` (lint + typecheck + tests)" to mention
format-check (e.g., "lint + format-check + typecheck + non-E2E tests") so the
poe check summary and the detailed list are consistent for the `poe check`
entry.

---

Outside diff comments:
In `@CLAUDE.md`:
- Line 78: Replace the bare command string "poe gen-gql" with the standardized
"poetry run poe gen-gql" in the CLAUDE.md occurrence that references
regenerating src/planpilot/core/providers/github/github_gql/ so the file matches
the Anti-Patterns section's usage; update the single remaining "poe gen-gql"
instance to "poetry run poe gen-gql".

---

Nitpick comments:
In @.claude/rules/coding-style.md:
- Around line 19-32: The code block places "from typing import NamedTuple" after
the User dataclass, which is non-idiomatic; move all imports to the top or split
into two labeled blocks so imports precede definitions. Specifically, ensure
"from dataclasses import dataclass" is grouped with the User dataclass
declaration (class User) and "from typing import NamedTuple" is placed before
the Point definition (class Point), or separate them into two distinct code
blocks labeled (e.g., "Frozen dataclass" and "NamedTuple") so each import sits
immediately above its related type definition.

In @.claude/rules/hooks.md:
- Around line 12-15: Add a concrete example JSON snippet to
~/.claude/settings.json that replaces the ambiguous "black/ruff" text with the
project-preferred "ruff" and shows the exact hook entries for Python files:
include a "hooks" object with a pattern for "*.py" and commands for formatting
using "ruff format" and for type checking using the chosen tool ("mypy" or
"pyright"), so reviewers can copy-paste the minimal working configuration rather
than researching the hook schema.

In @.claude/rules/security.md:
- Around line 23-26: The docs instruct running bandit but the project doesn't
declare bandit in pyproject.toml nor include it in the poe "check" pipeline;
either add a poe task (e.g., name it "security") that runs "bandit -r src/" and
include "security" in the poe "check" list, and add bandit to the project's dev
dependencies in pyproject.toml, or update .claude/rules/security.md to state
that running bandit is an optional manual step and mention that a poe task is
not provided by default; reference the bandit command, the poe "check" pipeline,
and pyproject.toml when making the change.

---
# Python Testing

> This file extends [common/testing.md](../common/testing.md) with Python specific content.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Minor grammar nit: "Python-specific"

The compound adjective modifying "content" should be hyphenated: "Python-specific content." The same nit applies to the identical phrasing in the other four rule files.

✏️ Suggested fix
-> This file extends [common/testing.md](../common/testing.md) with Python specific content.
+> This file extends [common/testing.md](../common/testing.md) with Python-specific content.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> This file extends [common/testing.md](../common/testing.md) with Python specific content.
> This file extends [common/testing.md](../common/testing.md) with Python-specific content.
🧰 Tools
🪛 LanguageTool

[grammar] ~8-~8: Use a hyphen to join words.
Context: ...ng.md](../common/testing.md) with Python specific content. ## Framework Use **p...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/testing.md at line 8, Update the compound adjective "Python
specific content" to the hyphenated form "Python-specific content" in this file
(the line that currently reads "This file extends
[common/testing.md](../common/testing.md) with Python specific content.") and
make the identical change in the other four rule files that use the same
phrasing so all five files consistently use "Python-specific content".

Comment on lines +27 to +34
@pytest.mark.unit
def test_calculate_total():
...

@pytest.mark.integration
def test_database_connection():
...
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Check whether pytest markers are registered in pyproject.toml
grep -n "markers\|mark\.unit\|mark\.integration" pyproject.toml || echo "No markers registered in pyproject.toml"

# Also check if pytest.ini exists
if [ -f pytest.ini ]; then
  echo "---"
  echo "Found pytest.ini:"
  cat pytest.ini
else
  echo "No pytest.ini found"
fi

# Check the full [tool.pytest.ini_options] section
echo "---"
echo "Full pyproject.toml [tool.pytest.ini_options] section:"
grep -A 20 "\[tool.pytest.ini_options\]" pyproject.toml || echo "No [tool.pytest.ini_options] section found"

Repository: aryeko/planpilot

Length of output: 693


Register custom pytest marks to suppress PytestUnknownMarkWarning

Custom marks @pytest.mark.unit and @pytest.mark.integration are not registered in pyproject.toml. Add them to the [tool.pytest.ini_options] section:

Suggested fix
[tool.pytest.ini_options]
markers = [
    "unit: mark test as a unit test",
    "integration: mark test as an integration test",
]

Without this registration, pytest emits PytestUnknownMarkWarning for every test using these marks.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.claude/rules/testing.md around lines 27 - 34, Register the custom pytest
marks "unit" and "integration" to avoid PytestUnknownMarkWarning by adding them
under the [tool.pytest.ini_options] section in pyproject.toml; specifically add
entries for the markers list that document "unit" and "integration" (so tests
that use `@pytest.mark.unit` and `@pytest.mark.integration` are recognized).

Arye Kogan added 2 commits February 22, 2026 22:10
- Fix missing poetry run prefix on poe gen-gql in Key Conventions
- Add format-check to Before Every Commit description
- Replace black/isort with ruff format/ruff check in coding-style.md
- Split non-idiomatic import+class code block into two labeled blocks
- Fix bandit note to clarify it is an optional manual step
- Replace black/ruff with ruff in hooks.md PostToolUse guidance
- Fix Python-specific hyphenation across all five rule files
Python-specific rules now live in ~/.claude/rules/python/ and apply
across all Python projects. Removes redundant project-level .claude/rules/.
@aryeko aryeko merged commit 8f6be3b into main Feb 22, 2026
13 checks passed
@aryeko aryeko deleted the docs/improve-claude-md branch February 22, 2026 20:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant