AI Fallbacks & Privacy
Two commitments that together define our AI posture.
Fallbacks: the product never depends on Claude
| Surface | Fallback if Claude unavailable |
|---|---|
| Triage | Keyword rules (HeuristicTriageAssistant) with confidence capped at 0.5 |
| Work-order scope | Tenant raw text; cost ceiling null; amber chip shown |
| Duplicate detection | Jaccard ≥0.35 over stopword-stripped tokens |
| Property suggestions | Rule cascade (overdue → due-soon → open WO age → insurance) |
| Owner digest | Static template with structured inserts |
Triggers for fallback:
- Transient Claude error (network, timeout, 5xx) — immediate fallback
- 3 consecutive failures — circuit breaker opens; all calls fall back for 5 minutes
- Rate limit hit — fallback; the Anthropic response headers guide the retry window
- Config missing —
ANTHROPIC_API_KEYnot set → fallback path wired at startup
Privacy: the AU privacy line
Only the tenant's report text is sent to AI for triage; no other personal details are transmitted.
This is verbatim in our FAQ and Terms. Plain-English version:
What we do send to Anthropic:
- The tenant's free-text maintenance report (for triage + duplicate detection)
- The triaged request's category + urgency + suggested actions (for scope draft)
- Aggregated WO metadata — scope, cost, date, status — stripped of tenant identity (for owner digest)
- Compliance rule friendly names + due dates (for property suggestions + digest)
- Property suburb / state / postcode (for scope draft context)
- Owner + PM first names (for digest salutation + sign-off)
What we strip before sending:
- Tenant name, email, mobile, surname
- Owner email, mobile, full name beyond first name
- Contractor contact details
- Full street address of properties (unit + street numbers)
- Internal database UUIDs
- Tenant payment / rent / arrears data (we don't have it anyway — PMS owns that)
- Financial figures beyond individual WO dollars
Why "only report text"
Three reasons, in order:
- Consent model. The tenant submitted the report text. That text is the consented data. Everything else about the tenant (their name, their email) was given for a different purpose (the PM knowing who to call) and shouldn't ride along to a third-party LLM.
- Data minimisation. Classical privacy principle — send the minimum necessary to accomplish the task. Triage needs text; it does not need an email address.
- Simplicity of the promise. "Only the report text" is a claim any PM can verify by reading their own network traffic. Complex privacy claims are hard to defend in a tribunal.
Where this is enforced
ClaudeTriageAssistant.triage()— receives onlyrawText, not the fullMaintenanceRequestClaudeDuplicateDetector.findDuplicates()— projects each candidate to{requestId, rawText}; no tenant fields carriedClaudeWorkOrderScopeDrafter.draft()— receivesContext(tenantReportText, category, urgency, address, triageSuggestedActions);addressprojected to suburb + state + postcode before sendClaudeDigestDrafter.draft()— receivesDigestContextwhosetoPrompt()method explicitly omits tenant/owner contact fieldsClaudePropertyAiSuggester.suggest()— receives summarised numeric + categorical state; no raw tenant text or contact fields
Each is covered by a unit test asserting the serialised Anthropic payload does NOT contain tenant email, mobile, or name strings.
Data residency
Anthropic's API serves from US + EU regions. Our Spring Boot calls hit
the standard api.anthropic.com endpoint, which Anthropic routes based
on request origin. For AU data-residency-sensitive agencies we can:
- Route through Anthropic's Bedrock (AWS) — supports ap-southeast-2 (Sydney). Requires switching from direct HttpClient to Bedrock SDK, which is on the roadmap.
- Or run with Claude disabled (heuristic-only mode) — set
ANTHROPIC_ENABLED=false.
See Legal & Compliance for the full AU privacy + AU data-residency statement.