aboutsummaryrefslogtreecommitdiff
path: root/claude-rules
Commit message (Collapse)AuthorAgeFilesLines
* docs(commits): document slack-deepsat MCP payload formatCraig Jennings2026-05-151-0/+11
| | | | The MCP's `conversations_add_message` tool takes the raw mrkdwn body in `payload`, not a Slack API JSON envelope. Wrapping the body in `{"text": "..."}` posts the literal JSON to the channel — `<@>` mention strips, escaped `\n` renders as a literal `n`, and the `text:` key prefix shows up in the post. Step 8 now documents the format + mrkdwn list so PR-review notifications don't garble.
* docs: codify depth-based completion rule + DRY the skill referenceCraig Jennings2026-05-151-5/+52
| | | | | | | | | | | | | | | Todo-format.md gets a "Completion — depth-based" section that codifies what was implicit before: top-level (* and **) DONE tasks stay task-shaped (DONE + CLOSED line), sub-tasks (*** and deeper) flip to dated event-log entries, and VERIFY is the documented exception (always dated-rewrite regardless of depth). The section includes worked examples and the rationale for depth-based over keyword-based. The cj-comments skill's completion section now references the canonical rule instead of restating the depth-based rules inline. The three-bullet recap in the skill stays as a quick scan, but the details and examples live in one place.
* docs(cross-project): prefer inbox-send for handoff dropsCraig Jennings2026-05-151-0/+10
| | | | | | | | | | | | | | | | The cross-project boundary rule already prescribes dropping a handoff file in the target project's inbox/ when option 1 ("do it from here") is chosen. The change adds a paragraph pointing at the new inbox-send script as the preferred tool for the drop. The script handles project discovery, source-project provenance in the filename, slug derivation, and timestamping in one call, replacing the hand-constructed filenames and guessed project paths the rule used to require. Filename convention is unchanged (YYYY-MM-DD-HHMM-from-<source>-<slug>.<ext>); the script just generates it instead of me typing it out. Fallback to Write/Edit is documented for cases where the script isn't installed (e.g. a freshly-cloned project before the first startup-rsync).
* docs: simplify cj-comments skill + add VERIFY placement/completion rulesCraig Jennings2026-05-151-0/+118
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Rounds of simplification on the cj-comments skill: converged on source-block-only in org files, dropped the non-org parsing entirely, factored out the mechanical parts into helper scripts (added separately in another repo), and codified the VERIFY placement + completion rules in a canonical rule file so the conventions stop being implicit. Skill (.claude/commands/respond-to-cj-comments.md): - Drop the file-type comment-marker table and the non-org multi-line continuation rule. The skill now recognizes only the org source-block form (#+begin_src cj: ... #+end_src). Craig's yasnippet keeps typing cost flat. - Defensive parsing for legacy inline cj annotations in older org files (back-compat). - Prefer the new helper scripts: step 1 calls cj-scan for structured detection; step 4 sub-step 6 calls cj-remove-block for validated removal. Both have explicit fallback paths to grep+Read / Edit. - Completion rules now split by keyword: TODO/DOING at *,** stay task-shaped (DONE + CLOSED); deeper TODO/DOING flip to dated headings; VERIFY at any depth flips to a dated heading with body replacement. - New VERIFY-answer pattern: when a cj's parent_heading_chain ends with VERIFY, the cj is the answer to that VERIFY. Lift its body into the dated rewrite (or execute the instruction first if indirect), then delete the cj. - New placement rule for new VERIFYs: sibling of the trigger heading, not a child. Climb to *** when the trigger is buried at ****+. This is the active force that keeps todo.org flat. - Rename "cj: comment" to "cj comment" in prose; preserve the literal cj: token in code examples and grep targets. Canonical rule (claude-rules/todo-format.md): - New "VERIFY tasks" section with four subsections: Placement (** or *** only), Creating a new VERIFY (sibling of trigger), Completion (dated rewrite + body replacement at any depth), Don't leave stale placeholders. - Worked before/after examples for both top-level and first-level VERIFYs.
* feat(rules): add todo-entry format (terse heading, optional body)Craig Jennings2026-05-131-0/+58
|
* feat(rules): cross-project boundary rule + cj-comments preflightCraig Jennings2026-05-131-0/+50
| | | | | | | | | | | | New `claude-rules/cross-project.md` codifies the per-project `.ai/` scope boundary. Stop-and-ask when a request targets another project's files, inline numbered options, handoff-file convention when the user opts to do it from here. `/respond-to-cj-comments` gains a section-0 preflight (boundary check before reading the target file) and a section-7 handoff step (writes the carry-forward file in the target project's `inbox/` when the boundary crossing was approved).
* fix(commits): correct PR-review notification channel IDCraig Jennings2026-05-131-1/+1
| | | | Step 8 of the publish flow referenced C0AM2MWHCJU as the channel for the Slack PR-author ping. That ID is actually a 3-person mpdm (Craig/Vrezh/Kostya), not the intended 4-person PR-review group. Corrected to C0B1B0NH2N5 (Craig/Eric/Vrezh/Kostya) and added a clarifying note that the 3-person mpdm is not an "#ai" channel despite older references calling it that.
* docs(commits): add Step 0 pre-flight reconcile and pre-push checkCraig Jennings2026-05-101-1/+51
| | | | | | | | The publish flow had no fetch step before commit, PR creation, or push. Long sessions or multi-machine work could land local commits on a stale base, producing non-fast-forward push failures that you have to unwind under publish-step pressure. Step 0 fetches all remotes and checks the current branch against its upstream before Step 1's code review. If the branch is behind, the rule branches on tree state and divergence shape: clean fast-forward, surface dirty-tree behind, or surface a true divergence and ask before rebasing or merging. The Step 0 wording covers the new-branch case (no upstream → skip the divergence check, the first push sets it). The Pre-push reconcile bullet in Merge Strategy handles the smaller window between Step 0 and the actual push. Reviewing and drafting can take several minutes; another machine or teammate can push during that window. One more fetch immediately before push is cheaper than recovering after a failed push.
* feat(claude-rules): add interaction.md — no popup menus for choicesCraig Jennings2026-05-081-0/+31
| | | | | | Codify the rule that AskUserQuestion's popup menu obscures the chat text the user needs to read to make the choice. Choice prompts go inline as numbered options instead, with a "pick a number" prompt at the end. Applies to all three approval gates in commits.md (commit message, PR description, PR review reply).
* fix(commits): anchor .ai/ detection to repo root with :/ pathspecCraig Jennings2026-05-071-2/+4
| | | | | | | | The detection command for personal vs. general voice mode used `git ls-files .ai/`, which returns no matches when run from a subdirectory of the repo, even when `.ai/` is tracked at the root. That silently misclassified projects as personal-voice when they should have been general-voice. Switching to `git ls-files :/.ai/` anchors the search to the repo root via the `:/` pathspec, so the command works correctly from any cwd. I hit this myself today: ran the check from `claude-rules/` inside the rulesets repo, got an empty result, and applied `/voice personal` to a commit that should have used `/voice` (general mode).
* docs(commits): add bundled-review shape, voice mode gating, drop humanizerCraig Jennings2026-05-071-16/+101
| | | | | | | | I rewrote the PR review subflow into three explicit shapes. Shape 1 is a single review that bundles the verdict, the summary body, and zero or more inline pins into one `gh api .../reviews` call. Shape 2 is an issue-thread comment with no verdict. Shape 3 is a reply on an existing inline thread. The single-review path replaces the prior pattern where a Request-Changes verdict with line-specific findings needed separate `gh pr review` + `gh pr comment` calls. That fragmented the Slack notification and the review history. I migrated all `humanizer` references to `/voice personal`. The voice skill replaced humanizer, so the old name was dead. I dropped the two lineage mentions of "humanizer's signs of AI writing" since they pointed at a skill that no longer exists. I added a Voice mode and approval gate preamble at the top of Step 2. The mode is decided by whether `.ai/` is tracked in the repo. Gitignored or absent means personal-voice with the full approval gate. Tracked means general-voice and the gate is skipped, since the personal-only patterns (first-person rewrite, contractions, semicolon swap) don't fit a shared rules file. I also updated the Single-skill gate wrap-up paragraph at the end of Step 2 to reference both modes.
* chore: migrate humanizer callers to /voice personalCraig Jennings2026-05-071-25/+22
| | | | | | | | | | I switched the three publish subflows in commits.md (commit messages, PR descriptions, PR review comments) from "run humanizer; apply five personal-style passes in order" to a single "run /voice personal" invocation. The new skill walks 39 patterns in one editorial review and absorbs the five passes wholesale, plus four more personal-style additions (felt-experience cut, fragment-in-prose rewrite, terse cut, public-artifact scope flag) and six universal good-writing patterns. The numbered steps in each subflow collapse from 5 to 4 (commits) and 9 to 8 (PRs) since the dedicated personal-style step folds into the voice invocation. The Multi-pass gate paragraph becomes a Single-skill gate. The mid-flow "all the passes" prompt now means re-run the full 39-pattern walk in personal mode rather than reapplying six discrete steps. I also updated respond-to-cj-comments.md to invoke /voice personal for public writing and /voice general for the lighter pass on internal notes when wanted, and updated start-work.md's Phase 7 summary to match. The humanizer skill itself stays in place for now. The next commit removes it.
* docs(commits): require @-mention of PR author in Slack notifyCraig Jennings2026-05-021-3/+3
|
* docs(commits): keep follow-up approvals terseCraig Jennings2026-05-021-0/+2
|
* docs(commits): drop "on" from Slack notify templatesCraig Jennings2026-05-021-2/+2
|
* docs(commits): add first-person voice as a personal-style passCraig Jennings2026-05-011-5/+5
| | | | | | I told Claude that the commit-message draft should sound personal, like it's coming from me. That move wasn't in the documented passes, so the drafts kept landing on impersonal third-person ("Add a test for X", "The change introduces Y"). I had to ask for the rewrite each time. First person is now the new pass (a) in all three subflows: commit messages, PR descriptions, PR review comments. The subject line and PR title stay imperative per Conventional Commits, and I left an exception for purely mechanical bodies where the subject already carries the message. I bumped the Multi-pass gate counts and the example announcement string to match.
* docs(commits): add post-review Slack notify + approve-vs-merge noteCraig Jennings2026-05-011-0/+7
| | | | | | | | Step 8 of the PR review/publish flow now sends a one-line message to channel C0AM2MWHCJU after every approve or changes-requested verdict. The new step skips humanizer and personal-style passes since the message is short and templated. The approve case sends "Approved on PR #N." with the PR URL on the next line. The changes-requested case sends "Changes Requested on PR #N" with the PR URL on the next line. I also added an explicit line saying approve doesn't authorize a merge. That keeps the merge decision with the PR author. The team's practice is approve-then-author-merges, not approve-and-merge.
* docs(commits): Conventional Commits spec + terminal-first reviewCraig Jennings2026-04-261-64/+135
| | | | | | | | | | | | | | | | | I reworked commits.md with two structural shifts and five smaller rule changes. Structural: - Drafts print inline in the terminal. `emacsclient` only opens when asked. Was: editor by default, humanize after. - Adopted the full Conventional Commits spec. New sections: Structure, Types, Scope, Breaking changes (`!` and `BREAKING CHANGE:` footer), Subject line, Body, Footers, How to write, Examples. Smaller: - Personal-tooling files (`claude-rules/*.md`, any `CLAUDE.md`, `.claude/`, `.ai/`, `SKILL.md`) aren't cited as authority in shared messages. State the reason, not the rule. Carve-out for when one of these files IS the change. - Voice and Focus opens with a colleague-tone framing. Four anti-patterns called out below it: no felt-experience narration, no verb-as-noun ("the ask", "a learn"), no sentence fragments in prose, and no first-person "I" for software behavior — all caught real drafting tics today. "Brief. Terse is fine." also tightened to "Brief. Terse is preferred." - Future-debugger framing added to message-writing guidance. Imperative summaries beat diary notes, and the body becomes a lightweight decision log of the constraint or tradeoff. - PR titles end with the ticket ID in parens, e.g. `refactor: drop dead check (SE-289)`. - Multi-pass gate tightened to match the new mandatory ordering.
* docs(testing): rewrite time-mocking helper rule to be language-agnosticCraig Jennings2026-04-251-7/+15
| | | | | | | | The original phrasing leaned on Lisp terms (let-bind, defvar) that don't translate to most other languages. Generalize to two named failure modes (infinite recursion against the mocked primitive, scope-shadowing that production callers can't see) with examples across Python, Lisp, Go, and JavaScript so the rule applies regardless of stack.
* docs(commits,testing): add merge strategy + multi-pass gate + time-mocking ↵Craig Jennings2026-04-252-0/+31
| | | | | | | | | | | | | | | | | safety commits.md gets two additions. A new "## Merge Strategy" section makes squash-merge the default for feature branches and requires explicit confirmation of the merge approach before pushing or merging. A new "Multi-pass gate" paragraph in Review and Publish requires every humanizer-flow pass to run and be named when declaring done, so silent skips become defects. testing.md gets a new bullet under "### Determinism": time/clock-mocking helpers must not recurse against the primitive they're mocking, and must not let-bind over a defvar — the binding shadows only inside the test scope, so production code reading the symbol still gets the original value (silent test miss).
* docs: split Linear vs PR structure; propagate content-scope rule to Tier 1 ↵Craig Jennings2026-04-242-5/+24
| | | | | | | | | | | | | | | skills Linear ticket bodies are now Problem + Fix only. PR descriptions keep the four-section format (Problem, Fix, Why this fixes it, How it was tested). Linear's GitHub integration handles the cross-link via the PR body's Linear: line. Cross-ref to the content-scope rule appended at the end of each Tier 1 skill that produces public artifacts: testing.md, arch-document, arch-decide, arch-design, review-code, respond-to-review, brainstorm, codify. Single-source the rule in commits.md, point at it from each output-producing skill.
* docs(commits): add content scope rule for public artifactsCraig Jennings2026-04-241-0/+27
| | | | | | | | PR descriptions, Linear ticket bodies, and PR review comments are visible to the team. New section codifies what not to mention (local paths, private repos, personal tooling) and a concise four-section structure for shipped-fix descriptions: Problem, Fix, Why this fixes it, How it was tested.
* docs(commits): require explicit reviewer requests on PR creationCraig Jennings2026-04-241-3/+12
| | | | | | | | | Adds step 7 to the Review-and-Publish PR-description flow: pass --reviewer at create time or use gh pr edit --add-reviewer right after. Notes that CODEOWNERS auto-suggestions aren't requests, that picking reviewers should follow the team's per-repo convention, and that follow-up PRs benefit from tagging the parent PR's author. Renumbers the Linear-comment and Dev-Review status steps accordingly.
* docs(commits): codify voice rules + PR-comment publish flowCraig Jennings2026-04-231-10/+22
| | | | | | | | Three new paragraphs under "Voice and Focus": first person where it fits, brief/terse, kind. The section now applies to PR comments (review replies, follow-up notes, thread responses) as well as commit bodies and PR descriptions. New "For PR review comments and replies" subsection under Step 2 mirrors the commit-message and PR-description flows: draft to /tmp/pr-<N>-comment.md, humanizer skill, plain-English pass, user approval, then post with the right gh command for the comment type. The trivial-one-liner exception at the bottom of Step 2 now covers acknowledgment-style replies ("thanks for the review") alongside trivial commits.
* docs(commits): add Voice and Focus, expand humanizer checklistCraig Jennings2026-04-221-2/+29
| | | | | | Added a new Voice and Focus section between Commit Message Format and Review and Publish. It covers three rules that kept coming up in practice. Write in the user's voice — first person fits, and "This PR introduces X" reads as press-release self-narration. Focus on what was wrong and what was corrected, not the mechanics. Don't stack three or more type signatures or API names in a single sentence. Also extended the post-humanizer checklist in both the commit-message and PR-description flows. Items (c) "prefer contractions" and (d) "break up long sentences" now sit alongside the existing (a) "rewrite dev-jargon" and (b) "replace semicolons". Uncontracted English reads stiff in short prose, and stacked-clause sentences read easier split on a conjunction.
* docs(commits): add review-and-publish flow, tighten message conventionsCraig Jennings2026-04-221-0/+87
| | | | | | | | | | Three additions to claude-rules/commits.md. A new conventions section adds two rules. First, do not hard-wrap commit body lines. Let the renderer soft-wrap instead. Hard wraps shrink the visible width in web UIs and cause awkward mid-sentence breaks. Second, do not reference how the change was produced (code review, linting, test runs) in the message. The body is for the what and the why. The how belongs in the PR discussion. A new Review and Publish section defines a two-step gate for every commit and PR. Step 1 runs /review-code against the change and blocks on Critical or Important findings unless the user overrides. Step 2 drafts the message to /tmp, opens it in the user's editor, runs the humanizer skill, and waits for explicit approval before committing or pushing. PRs also require a Linear cross-link line, a Linear comment with the PR URL after creation, and a status transition to Dev Review. A short hook-level authorization note clarifies that the review-plus-approval flow is the authorization gate. Tools like git-commit-confirm should not add a second independent prompt once Step 2 has been approved.
* feat(rules): add subagents.md — when, how, and when not to delegateCraig Jennings2026-04-191-0/+126
| | | | | | | | | | | | | | | | | | | | | | | | | | Cross-cutting rule covering subagent hygiene: - Decision table: parallel-safe (read-only investigation, independent test failures, multi-domain research) vs sequential-with-review (plan execution, coupled edits) vs never-parallel (concurrent writes) vs don't-subagent-at-all (target known, work fits in ~10 tool calls). - Prompt contract: scope / pasted context / explicit 'do NOT' list / required output format. Missing any field yields shallow work. - Context-pollution rule: subagents absorb noise the main thread shouldn't carry. When one fails, dispatch a fix-agent with the failure report — do not retry in the orchestrator. - Review-gate cadence: after each sequential task, or every ~3 in parallel batches. - Anti-patterns including parallel implementation on overlapping files, broad 'fix all the tests' prompts, timeout-tuning to mask flakes, and letting the agent decide scope. Added one-line cross-references to subagents.md from debug/, review-code/, and finish-branch/ SKILL.md — the skills that most rely on delegation. Clean-room synthesis from NeoLabHQ/context-engineering-kit's subagent-driven-development pattern (MIT).
* feat: adopt pairwise-tests (PICT combinatorial) + cross-reference from ↵Craig Jennings2026-04-191-0/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | existing testing skills Forked verbatim from omkamal/pypict-claude-skill (MIT). LICENSE preserved. Renamed from `pict-test-designer` to `pairwise-tests` — technique-first naming so users invoking "pairwise" or "combinatorial" find it; PICT remains the tool under the hood. Bundle (skill-runtime only): pairwise-tests/SKILL.md (renamed, description rewritten) pairwise-tests/LICENSE (MIT, preserved) pairwise-tests/references/pict_syntax.md pairwise-tests/references/examples.md pairwise-tests/scripts/pict_helper.py (Python CLI for model gen / output fmt) pairwise-tests/scripts/README.md Upstream's repo-level docs (README, QUICKSTART, CONTRIBUTING, etc.) and `examples/` dir (ATM + gearbox walkthroughs — useful as reading, not as skill-runtime) omitted from the fork. Attribution footer added. Cross-references so /add-tests naturally routes to /pairwise-tests when warranted: - add-tests/SKILL.md Phase 2 step 8: if a function in scope has 3+ parameters each taking multiple values, surface `/pairwise-tests` to the user before proposing normal category coverage. Default continues with /add-tests; user picks pairwise explicitly. - claude-rules/testing.md: new "Combinatorial Coverage" section after the Normal/Boundary/Error categories. Explains when pairwise wins, when to skip (regulated / provably exhaustive contexts, ≤2 parameters, non- parametric testing), and points at /pairwise-tests. - languages/python/claude/rules/python-testing.md: new "Pairwise / Combinatorial for Parameter-Heavy Functions" subsection under the parametrize guidance. Explains the pytest workflow: /pairwise-tests generates the matrix, paste into pytest parametrize block, or use pypict helper directly. Mechanism note: cross-references are judgment-based — Claude reads the nudges in add-tests/testing/python-testing and acts on them when appropriate, not automatic dispatch. Craig can still invoke /pairwise-tests directly when he already knows he wants combinatorial coverage. Makefile SKILLS extended; make install symlinks /pairwise-tests globally.
* feat(rules): port key testing principles from quality-engineer promptCraig Jennings2026-04-191-0/+104
| | | | | | | | | | | | | | | | | | | | | | | Additions to claude-rules/testing.md: - Testing pyramid proportions (70-80% unit / 15-25% integration / 5-10% e2e) - Integration Tests section: docstring must name 'Components integrated:' and mark real vs mocked; when-to-write heuristics - Signs of Overmocking: 'would the test pass if the function body was NotImplementedError?' plus three more sharp questions - Testing Code That Uses Frameworks: test your integration, not the framework itself - Test Real Code, Not Copies: never inline prod code into tests - Error Behavior, Not Error Text: test type + key values, not exact prose - If Tests Are Hard to Write, Refactor the Code: hard-to-test is a code signal, not a test signal; extract focused helpers - Anti-patterns list extended Addition to languages/elisp/claude/rules/elisp-testing.md: - Interactive vs Internal split pattern: cj/foo wraps cj/--foo; test the internal directly, skip UI mocks Source: ~/.emacs.d/ai-prompts/quality-engineer.org (personal reference, kept as an extended prompt separate from these rules).
* feat: add commits.md rule — no AI attribution anywhereCraig Jennings2026-04-191-0/+66
| | | | | | | | | | | | | | New generic rule at claude-rules/commits.md covers author identity, absence of Claude/Anthropic/LLM/AI attribution (messages, PRs, comments, trailers, emojis), and conventional commit format. Applies to all repos. Bundle settings.json now sets attribution.commit: "" and attribution.pr: "" so Claude Code's default attribution is suppressed belt-and-suspenders with the written rule. Elisp CLAUDE.md template trimmed to reference commits.md instead of inlining the rules.
* refactor: generalize testing.md, split Python specifics, DRY installCraig Jennings2026-04-191-4/+17
| | | | | | | | | | | | | | | | | | | claude-rules/testing.md is now language-agnostic (TDD principles, test categories, coverage targets, anti-patterns). Scope header widened to **/*. Python-specific content (pytest, fixtures, parametrize, anyio, Django DB testing) moved to languages/python/claude/rules/python-testing.md. Added languages/python/ bundle (rules only so far; no CLAUDE.md template or hooks yet — Python validation tooling differs from Elisp). Added install-python shortcut to the Makefile. Updated scripts/install-lang.sh to copy claude-rules/*.md into each target project's .claude/rules/. Bundles no longer need to carry their own verification.md copy — deleted languages/elisp/claude/rules/verification.md. Single source of truth in claude-rules/, fans out via install. Elisp-testing.md now references testing.md as its base (matches the python-testing.md pattern).
* Add general-purpose skills and rules from DeepSat coding-rulesetsCraig Jennings2026-03-292-0/+182
Skills (adapted from DeepSat, stripped of project-specific references): - /review-pr: PR review against engineering standards - /fix-issue: issue-to-merge TDD workflow - /security-check: secrets, OWASP, and dependency audit - /debug: systematic 4-phase debugging - /add-tests: test coverage analysis and generation - /respond-to-review: evaluate and implement code review feedback Rules (general-purpose, copied as-is): - testing.md: universal TDD standards and anti-patterns - verification.md: proof over assumption Makefile updated to install both skills and rules via symlinks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>