diff --git a/CLAUDE.md b/CLAUDE.md index f522e8b..58cab74 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -92,6 +92,29 @@ Frontend: React 19 + Vite + Tailwind 4 + TanStack Router/Query, built into - **Every service mutation lands in history** (#48). If you add one, record it — see `internal/service/revisions.go`. Multi-row operations pass all their changes to a single `record` call so they undo as one unit. +- **The history write is detached from cancellation on purpose.** `commitScope` + calls `context.WithoutCancel` — that is not a mistake to tidy up. By the time + a commit runs, the rows it describes are already written, so cancelling it + cannot undo anything; it can only leave real changes with no way to undo them. + This was a live bug twice (#73): a client disconnect mid-request orphaned 18 + plantings. Fixing it per-call-site is how it came back, which is why the rule + lives in `commitScope` where no caller can forget it. + +## Testing + +Match the test to the failure it would catch: + +- **Anything addressed by its own id needs an API-level test through the router.** + Service tests can't see a route that was never registered — PATCH/DELETE + `/journal/:id` once shipped fully implemented, fully unit-tested, and + completely unreachable. +- **Watch for fixtures that assert your assumptions instead of the API.** A test + for the undo message passed because the fixture I wrote populated a field the + real response leaves empty. If a test builds the thing it's testing against, + it is checking your mental model, not the system. +- Some things only real use finds. The agent's whole loop is covered by + majordomo's scriptable fake provider (`provider/fake`), which is worth using — + but the three worst v2 bugs all turned up in one live session afterwards. ## Workflow