From 20de0eca58802bc778b5a0103c6b910762b447a4 Mon Sep 17 00:00:00 2001 From: Craig Jennings Date: Sat, 25 Apr 2026 01:30:28 -0500 Subject: docs(commits,testing): add merge strategy + multi-pass gate + time-mocking safety MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- claude-rules/testing.md | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'claude-rules/testing.md') diff --git a/claude-rules/testing.md b/claude-rules/testing.md index 02c6ce0..a6bc1df 100644 --- a/claude-rules/testing.md +++ b/claude-rules/testing.md @@ -158,6 +158,13 @@ the specific case choice. - Never hardcode dates or times — generate them relative to `now()` - No reliance on test execution order - No flaky network calls in unit tests +- Time/clock-mocking helpers must not call the primitives they're + mocking (infinite recursion), and must not `let`-bind over a + `defvar` or other globally-defined symbol (the binding shadows the + global only inside the test scope, so production code that reads the + symbol gets the original value, not the mock — silent test miss). + Mock by redefining at the symbol's definition site or via the + language's first-class mocking primitive. ### Performance - Unit tests: <100ms each -- cgit v1.2.3