familylaw.ai.client:
- _log_failure_durably(vals): writes a 'failed' ai.task in an INDEPENDENT
transaction (self.env.registry.cursor() + commit) so the failure survives the
rollback of the calling transaction (the audit/cost ledger keeps a record of
failed calls, not just successful ones). Exceptions inside are swallowed so audit
logging can never mask the original error.
- _purge_task_ids(ids): delete ai.task rows in an independent transaction (prune old
failure logs).
- generate() failure path now routes to _log_failure_durably with full metadata
(task_type, provider, model, case/proceeding, error, latency) and still re-raises.
Tests (familylaw_step6): test_11 verifies the failure-row write logic + case linkage
(registry cursor pointed at the test txn, since TransactionCase forbids real commits);
test_12 spies that generate routes provider errors to durable logging with correct
vals; test_07 asserts the error still propagates.
Verified in live Odoo 18: 200 tests, 0 failed, 0 errors, clean log.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>