Environment-specific runbook covering: pre-flight checklist (incl. the non-code
launch-blockers from CLAUDE.md §11), db1 backup, staging, install (Apps UI + CLI
methods), post-install verification (matches the dry-run checks), system-parameter
configuration (Claude / CourtListener / DocuSeal keys + which features each unlocks),
the two-gate guarantees, rollback/uninstall via pre-install dump, and known
non-blocking follow-ups. Coexistence with the legacy module documented throughout.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Production already has a DIFFERENT, earlier module installed as `activeblue_familylaw`
(models fl.*, real data). Renamed this build's technical name to
`activeblue_familylaw_v2` so it installs ALONGSIDE the legacy app instead of replacing
it. Models (familylaw.*) and test tags (familylaw_step<N>) are unchanged — only the
module name and its group XML IDs change.
Changes:
- Folder activeblue_familylaw -> activeblue_familylaw_v2 (git mv)
- All 44 dotted refs activeblue_familylaw. -> activeblue_familylaw_v2.
(security group XML IDs in views/python; test patch targets odoo.addons.*)
- Manifest display name -> "Active Blue Family Law v2"; root menu -> "Family Law (v2)"
- scripts/validate_module.py ROOT path; BUILD_STATUS.md run commands + coexistence
note; START_HERE.md pointer
Verified in live Odoo 18:
- Fresh install + full suite: 200 tests, 0 failed, 0 errors.
- COEXISTENCE on a clone of prod db1: installing _v2 alongside the installed legacy
activeblue_familylaw left the legacy untouched (still installed 18.0.1.0.0, fl.*
models registered, fl_caselaw 25 rows intact) while adding the 30 familylaw.* models.
Exit 0, no errors. Clone dropped; prod DBs untouched.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
name (computed) and issue_type both used label "Issue", which Odoo warns about at
load. Renamed the computed field's label to "Issue Label".
Verified: clean module install AND clean upgrade from the prod-deployed version on a
clone of production db1 (prod image + prod addons set, throwaway DB, dropped after).
Full suite still 200 tests / 0 failures.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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>
Ran the full familylaw suite in a one-off odoo:18.0 container against an isolated
throwaway DB. Fixes found and applied:
- All mail.thread-only models also inherit mail.activity.mixin — their form chatters
reference activity_ids (install-time ParseError on familylaw.deadline et al.).
- familylaw.archive.is_destruction_eligible: added a `search` method (non-stored
computed boolean used in a search-view filter domain was unsearchable).
- familylaw.archive.action_destroy: sudo() the ir.attachment unlink (attorney isn't
the attachment owner -> AccessError on destroy).
- test_step2 test_10: use relativedelta(years=8) not 365*8 days (leap-year drift made
age compute to 7; the age code is correct).
- familylaw.ai.generate failure path: keep best-effort failed-state write but document
that it rolls back with the failing txn; the real guarantee is error PROPAGATION.
test_step6 test_07 rewritten to assert the provider error propagates (never silently
swallowed) rather than asserting non-durable persistence.
BUILD_STATUS.md updated: tests now verified green in live Odoo.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
familylaw.comms — client communications drafted (optionally AI-assisted) for attorney
review: draft -> approved (attorney-only) -> sent. NEVER auto-sends; action_send
requires prior approval and an explicit human action. Staff draft/assemble but do not
communicate legal positions (Bar Rule 4-5.3).
familylaw.time.entry — time with an ai_assisted flag. Case computes total_hours,
ai_assisted_hours, ai_assisted_ratio (reportable AI-assisted share).
Matter-scoped access (security/familylaw_security.xml): record rule confines staff to
matters they are assigned to or created; attorneys see all (OR-combined rules). Bar
Rule 4-5.3 supervision + confidentiality.
Case gains Communications + Billing/Time tabs; Communications menu; ACL for both
models. Hardening (encryption-at-rest/backups) noted as infra, out of module scope.
Tests (familylaw_step14): cannot send draft (never auto-send); approve-then-send;
approve attorney-only; AI-assist ratio (25% of 8h) + zero case; staff sees assigned /
cannot see unassigned (search empty + read AccessError); attorney sees all.
This completes the Step 1-14 roadmap.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
familylaw.obligation (per case): status_quo_order / parenting_course / mediation,
state pending/completed/waived, complete + waive actions.
familylaw.case (_inherit):
- create() seeds AO 14-13 obligations for Miami-Dade matters (idempotent,
_seed_miamidade_obligations): Status Quo Order on dissolutions; Parenting Course on
children matters (dissolution_children/paternity/parenting_modification); Mediation
on all Miami-Dade matters. Non-Miami-Dade seeds nothing.
- action_set_hearing() now guards course-before-judgment: blocked while a required
parenting course is pending (children matters); allowed once completed.
Obligations tab on the case form. ACL added.
Tests (familylaw_step13): seeding by case type; no-children excludes course;
non-Miami-Dade no seed; idempotent; guard blocks/passes directly and across the full
lifecycle path; no-children not blocked; complete/waive.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
familylaw.support.modification — wires Steps 1-8 for a support modification:
- open_for_case() opens a NEW modification proceeding under the same case (locked
decision) and sets a 20-day answer deadline on it
- 15%/$50 substantial-change PRESUMPTION: threshold = max($50, 15% of current);
meets_threshold computed. Explicitly a deterministic test, NOT a prediction of
whether the court grants it (no outcome/probability — EXCLUDED capability honored)
- DOR / Title IV-D flag; retroactivity to filing date + note
- prior-judgment handling: action_extract_prior_judgment produces a plain summary +
FLAGGED interpretation QUESTIONS (carries a not-a-conclusion disclaimer); the model
has no conclusion/ruling field by design. AI call mocked.
Wizard + views + menu; "Open Support Modification" button on the case form (shown
for support_modification matters). ACL added.
Tests (familylaw_step9): new proceeding created + distinct from original; threshold
15% prong, $50 prong (met/not), change %, no-change; 20-day answer deadline + date
math; DOR flag; retroactivity date; extraction summarizes + flags (not concluded,
no conclusion field); extraction logs a done ai.task.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
familylaw.discovery.request (per proceeding):
- discovery_type incl. nonparty_production (Rule 12.351)
- HARD objection-window gate: a non-party subpoena cannot issue before notice is
served + the 10-day objection window elapses, or while an objection is pending
(_ensure_objection_window_elapsed). Party discovery is not gated.
- issuance_route computed from representation: attorney issues directly, pro se via
the clerk (Forms & Playbook Part C)
- on issue: Notice of Issuance served the SAME DAY; response due +30 days
- objection_deadline (+10, weekend roll) and response_due (+30, roll) computed
- VERIFY note: Rule 12.410 subpoena amendment eff. Oct 1 2025
Proceeding gets a Discovery tab; discovery views + menu + ACL.
Tests (familylaw_step8, fixed dates): cannot issue before notice / before window /
with pending objection; can issue after window; 10-day deadline math with weekend
roll; same-day notice of issuance; attorney vs clerk routing; party production not
gated; serve-notice transition; proceeding linkage.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
TIER 3 scaffolding — structure built, legal CONTENT born unapproved/unverified and
NOT authoritative until attorney validation. External calls mocked in all tests.
familylaw.ai.client (AbstractModel service):
- _route_model() pluggable provider seam (Ollama = future config flip)
- BLOCKED_TASK_TYPES (trust_billing/reconciliation/iota) RAISE before any call —
trust/billing never reaches a model (Bar Rule 5-1.1, IOTA)
- per-task token ceiling caps max_tokens; config via ir.config_parameter
- _call_provider isolates the real HTTPS call (the single mock point)
- generate() routes, calls, and logs an ai.task; returns (result, task)
familylaw.ai.task — the audit/economics ledger: model_used, prompt/completion/total
tokens, estimated cost_usd (per-model price table, flagged estimate), latency_ms,
request/response summaries, error, links to case/proceeding/document.
familylaw.citation — born 'unverified' (Gate 2 verification + filing block come in
Step 7); is_verified computed; linked to document + source ai.task.
familylaw.document.ai_assemble(): single-shot drafting agent — doc born ai_draft
(source ai), proposed citations born unverified, task linked. NOT auto-approved.
Plus familylaw.ai.draft.wizard for the UI walkthrough; Citations tab on document;
AI Draft button on proceeding; AI Tasks + Citations menus.
Tests (familylaw_step6, mocked _call_provider): doc born ai_draft, ai.task logged
with model+tokens+cost+latency, citations born unverified, token ceiling caps
max_tokens, trust/billing blocked before any provider call, provider error marks
task failed, deterministic cost estimate, missing-key raises, AI draft cannot be
filed even by an attorney (Gate 1 intact).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Three per-proceeding models:
- familylaw.disclosure.item: Rule 12.285 checklist; is_mandatory items refuse
waiver in code (action_waive raises); non-mandatory can be waived
- familylaw.financial.affidavit: form-by-income selection — short 12.902(b) below
the $50,000 gross-annual threshold, long 12.902(c) at/above it; 45-day due date
(Rule 12.285(e)) with weekend roll; line totals + net worth
- familylaw.fin.line: income/expense/asset/liability line items
All thresholds/counts flagged "verify current rule" (volatile FL law).
proceeding gets disclosure_item_ids + affidavit_ids, Seed Disclosure Checklist
button, and Disclosure / Financial Affidavits notebook tabs. Views + menu + ACL.
Tests (familylaw_step5): 15 tests — form selection across the threshold boundary
(49999 short / 50000 long / 80000 long), recompute on income change, 45-day due
with/without weekend roll (fixed dates), mandatory-cannot-waive, non-mandatory
waive, totals + net worth, idempotent seeding, per-proceeding isolation.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Models:
- familylaw.party — party to a matter (client/opposing/opposing counsel/other)
- familylaw.child — minor child with DOB constraint (rejects future + >25 years)
- familylaw.issue — contested issue (time-sharing, support, equitable distribution, etc.)
- familylaw.proceeding — unit of legal action; auto-created on every case create()
- familylaw.conflict.hit — records of conflict screening hits for attorney review
- familylaw.intake.wizard — multi-step intake questionnaire (TransientModel)
familylaw.case updates:
- case_number (indexed, unique, searchable), county, is_emergency, urgency_notes
- One2many to party/child/issue/proceeding/conflict_hit
- create() override: auto-opens an initial proceeding typed by case_type
- action_run_conflict_screening(): full-DB party + client name search; never auto-clears gate
Intake wizard (conditional strictness):
- Triage step first; urgency screen selects emergency vs. standard path
- Emergency fast-path: create on minimum facts (who + urgency flags), defer rest
- Standard strict path: matter name + client + case type + county required
- Modification branch (step 3) for support/parenting/alimony modifications
- Caller concern logged on case as attorney question; software never answers it
- Runs conflict screening on completion
Views: party/child/issue/proceeding/intake form+list+inline views; case form now
shows emergency banner, conflict warning, notebook tabs for all related records;
search extended to find by party name, child name, case_number (filter_domain).
Menu: "New Intake" entry launches the wizard.
Security: access rules for all 5 new models + intake wizard (base.group_user).
Tests (familylaw_step2): 34 tests across 4 classes covering:
- Initial proceeding creation and type mapping
- Multiple independent proceedings per case
- DOB validation (future + implausible age)
- Search by party name / child name / case_number
- Conflict screening (finds client match, does not auto-clear, hit count, no false
positives for unrelated parties)
- Standard path strict validation (missing name/type/county/client each rejected)
- Emergency path (creates case on caller name alone, sets is_emergency, captures notes)
- Caller concern logged on chatter, never answered by software
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Delivers the validated Step 1 slice of the Active Blue Family Law platform
(Odoo 18 Community module `activeblue_familylaw`):
- familylaw.case model: identity, team, representation flag, conflict_check_cleared gate
- Full lifecycle state machine (intake→engaged→disclosure→discovery→mediation→hearing→closed)
- Attorney-only guards enforced in Python + view groups=
- Security groups (Family Law/Staff, Family Law/Attorney), model access rules
- List, form, and search views (Odoo 18 <list> syntax; no attrs=/states=)
- Family Law app menu with Configuration placeholder
- 10 tagged unit tests (familylaw_step1): transitions, conflict gate, attorney-only, audit
- CLAUDE.md, BUILD_PLAN.md, START_HERE.md: full design brief and step contract
Step 2 (parties, children, issues, proceeding model, conflict screening,
intake questionnaire) is the next build target.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>