Every write tool repeated two shapes. Resolving a record in the space was
copy-pasted five times (account, transaction, category, label, and the rule
resolver, which existed twice — once in UpdateAutomationRule and once in
DeleteAutomationRule), each with the same query, null check and message
template. And each update tool walked its fields with a wall of
'if ($request->has(x)) { $model->x = ... }' blocks.
Both now live in WriteTool: modelInSpace() resolves any space-scoped model with
the same failure message, and applyFields() assigns just the fields the request
carries, taking closures so a related lookup only runs when its field is
present.
UpdateTransaction::write drops from cyclomatic complexity 20 to 7 and
UpdateAutomationRule::write from 13 to 6.
Adds the missing coverage for the failure messages, which nothing asserted
before: with a listing hint, and without one.