diff options
Diffstat (limited to '.claude/rules')
| -rw-r--r-- | .claude/rules/elisp-testing.md | 6 | ||||
| -rw-r--r-- | .claude/rules/interaction.md | 10 |
2 files changed, 16 insertions, 0 deletions
diff --git a/.claude/rules/elisp-testing.md b/.claude/rules/elisp-testing.md index b727cbd5..7c3a9efc 100644 --- a/.claude/rules/elisp-testing.md +++ b/.claude/rules/elisp-testing.md @@ -37,6 +37,12 @@ Every non-trivial function needs at least: Missing a category is a test gap. If three cases look near-identical, parametrize with a loop or `dolist` rather than copy-pasting. +### Measuring it — `make coverage-summary` + +The bundle ships a coverage summary at `.claude/scripts/coverage-summary.el` and a Makefile fragment (`coverage-makefile.txt`) with `coverage` and `coverage-summary` targets. After `make coverage` writes an undercover SimpleCov report, `make coverage-summary` prints a per-file table and a unit-weighted project number. + +The number to watch is the missing-file count. A module no test loads never appears in the SimpleCov report, so a line-weighted total skips it silently — the suite looks healthier than it is. The summary counts every `modules/*.el` on disk that's absent from the report as 0%, so an untested module drags the project number down where you can see it. Copy the fragment's targets into your own Makefile to adopt it; the bundle never edits your Makefile. + ## TDD Workflow Write the failing test first. A failing test proves you understand the change. Assume the bug is in production code until the test proves otherwise — never fix the test before proving the test is wrong. diff --git a/.claude/rules/interaction.md b/.claude/rules/interaction.md index 83afc45a..fa09d6d0 100644 --- a/.claude/rules/interaction.md +++ b/.claude/rules/interaction.md @@ -30,6 +30,16 @@ Reserve `AskUserQuestion` only when the user explicitly asks for the popup form This rule applies to all three approval gates in the `commits.md` publish flow (commit message, PR description, PR review reply): print the draft inline, then offer numbered approve / changes / edit options inline. Do not switch to the popup form for the gate even though the prior protocol referenced it. +### Order options with the recommendation at item 1 + +When the question has a clear recommended option, put it at item 1. The other paths stay visible so the user can override without having to type a custom answer, but the common case collapses to a single keystroke. + +Default to this pattern whenever the user needs to weigh a genuine choice — task-review actions, brainstorm decisions, judgment calls, approve/edit/cancel gates, "what should I do next" prompts. Skip it only when the question is free-form (open prose, names, dates), when the user has already issued a directive and a single confirmation suffices, or when there is no clearly-recommended option (in which case state that plainly: "I don't have a recommendation here — what's your read?"). + +Include a "Skip" / "Defer" / "Tell me how" as the last option when the user's answer might be "none of these." + +The convention reinforces the popup-denial rule above by giving every inline choice list a single canonical shape, and it forces the model to actually pick a recommendation rather than offering a neutrally-ordered enumerate-and-defer list. A neutrally-ordered list is a covert way to push the decision back; recommendation-first puts skin in the game. + **Enforcement:** a global `PreToolUse` hook (matcher `AskUserQuestion`) in `~/.claude/settings.json` hard-denies the popup and returns this rule as the reason — the prose alone proved too easy to forget. Because the deny is unconditional, the "use the popup for this one" exception above can't be honored in-turn; to get the popup, disable the hook via `/hooks` (or edit settings) first. ## No Reverse-Video Highlighting in Chat Output |
