| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Three changes to the same layer.
I split testing.md the way I split commits.md, by what has to be resident rather than by size. What stays is the standing directive: TDD is the default, write the failing test first, and every unit needs Normal, Boundary, and Error cases. That has to fire before any code is written, which is exactly when no skill has been summoned, so it can't ride a trigger. Everything else moved to the testing-standards skill: characterization recipes, the per-category detail, property-based and mutation testing, the pyramid, integration rules, naming, the test-quality and mocking rules, coverage targets, the spike exception, and the anti-patterns. 2,824 words down to 347.
I fixed the approval gate in the publish flow. It decided whether to ask for approval by checking whether .ai/ is tracked, using that as a proxy for "team repo." The proxy was wrong in the direction that matters: rulesets, home, and work all track .ai/ while all three are private single-user repos, so the rule skipped the gate on the three projects I use most. It now checks whether any remote is on a host other than cjennings.net, which is the thing that actually decides whether someone else reads the log. Every current project resolves to gate-applies, which matches how the flow has actually been run.
I also added a first-person directive to the always-loaded core. One already existed for commit bodies and PR prose, but it moved into the publish skill with everything else, and it never covered code comments at all. Now everything I author in or about the repo is first person, with one carve-out: a comment describing what the code does stays third person, because there the code is the actor and not me.
Separately I split the publish skill internally. PR descriptions and the three review shapes moved to references/pull-requests.md, since a plain commit never needs them.
Always-loaded rules are now about 28,900 tokens, down from 57,800 this morning.
One risk on the record. testing.md's margin is thinner than commits.md's was. If testing-standards fails to trigger while I'm writing tests I lose the mocking-boundary rules, which is a quality regression rather than a permanent one, but it is a real bet where commits.md's was not. I also moved the TDD rationalization table rather than cutting it. The posts argue that kind of over-argument is counterproductive now, but removing your defense against me skipping TDD is your call, not mine.
|
| |
|
|
|
|
|
|
|
|
|
|
| |
quality sweep
The rule already said "write a characterization test before refactoring" but not what one is or how many to write per unit. Two additions close that.
testing.md's "Adding Tests to Existing Untested Code" now defines a characterization test as recording what the code actually does, not what it should (Feathers' assert-wrong-read-the-real-value recipe), and requires the same Normal/Boundary/Error set as any unit rather than one happy-path capture. The reason is the useful part: on a characterization test the negative and boundary cases are the bug-finders, because untested legacy code is weakest at the empty input and the missing upstream, and pinning what it currently does there writes the wrong behavior down where it becomes a visible bug. A pinned case that turns out to be a bug graduates from recording current behavior to asserting correct behavior. In-unit bugs fall to this set. Composition bugs need a functional test.
The refactor-for-testability section gains the framing that when the untestable code is legacy you're hardening, extracting the pure core is the hardening, not a detour around it. A function you can't characterize without mocking tmux or git can't be refactored safely, so "needs too much mocking" is the signal to reshape it, never a license to skip the boundary and error cases.
code-quality.org's passes claim to preserve behavior, so it now states the precondition that makes that true: on untested scope, a characterization net comes first, or "behavior-preserving" is an assertion the green suite can't actually verify.
|
| |
|
|
| |
Two additions. An "Escalation Beyond Category and Pairwise" section adds property-based testing (for invariants across a broad input domain) and mutation testing (for when high coverage hides thin assertions), both as escalation paths rather than always-on gates. And the "I need to spike first" excuse is formalized into a disciplined spike protocol: TDD stays the default, but a spike is sanctioned only when timeboxed, not committed, and followed by the first failing test before productionizing.
|
| |
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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).
|
|
|
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>
|