The model interprets. The rules decide. You approve.
A quote is a commercial commitment made on incomplete information. So the parts of this product that can cost money — readiness, inspection routing, safety escalation — are deterministic code that anyone can read and test, and the parts that need judgement about language are handled by a model whose output is validated before it is trusted.
Who owns which task
| Task | Owner | How |
|---|---|---|
| Reading messy customer text | AI | gemini-3.6-flash, one multimodal call, strict JSON validated with Zod |
| Reading photos as evidence | AI | Certainty-labelled, never decisive on its own |
| Transcribing a spoken site note | AI | ElevenLabs Scribe (scribe_v1) — the only transcription provider |
| Rewording the recommended next step | AI | Wording only; the action type is already decided by rules |
| Retrieving relevant service guidance | AI | gemini-embedding-001 embeddings over 46 curated playbook notes, cited |
| What a job needs to be quotable | RULES | Per-type required-field templates |
| Readiness score 0–100 | RULES | Weighted formula, every component visible |
| Inspection and safety routing | RULES | Deterministic overrides + regex safety patterns on the customer's own words |
| Build and version the scope pack | RULES | Pure function: facts in, reviewable pack out |
| Approving anything the customer sees | HUMAN | Drafts stay drafts until a licensed operator approves them |
| Setting prices | HUMAN | AI never produces a figure; the operator prices every line |
The analysis graph (LangGraph)
One explicit, ordered pipeline. Retrieval and wording run strictly after the rules engine, which is what makes "AI cannot change the score" a structural property rather than a promise.
- 1. validate_job_inputrulesRejects empty or trivial input before any model call.
- 2. extract_job_facts_with_geminiaiUnstructured enquiry + photos → facts, evidence and risk flags. Honest fallback if the API fails.
- 3. validate_structured_outputrulesZod contract at the model boundary. Malformed output never reaches the engine.
- 4. apply_job_template_rules_and_scorerulesMissing fields, score components, overrides, safety escalation, recommended action.
- 5. retrieve_service_guidanceaiVector or keyword search over the curated playbook. Advisory, cited, never decisive.
- 6. generate_recommendation_with_aiaiRewords the action the rules already chose, optionally sharpened by retrieved guidance.
- 7. persist_analysisioNew scope version + audit event + run telemetry (latency, tokens, cost estimate).
Readiness scoring
score = 25%·details + 25%·evidence + 20%·access + 15%·confirmation + 15% ·risk
- Missing critical field → capped at 69.
- Inspection condition or safety pattern → capped at 69, action re-routed.
- Bands: 0–39 needs information · 40–69 inspection recommended · 70–100 ready for estimate.
- Every override is written out in plain English on the scope, with the reason.
Service guidance (retrieval)
- Corpus in code. 46 curated playbook notes, version-controlled and cited — not a scraped document dump.
- Query from facts only. The search text is built from the structured facts and risk flags, never from the model's prose or the tradie's spoken words.
- Vector or keyword. pgvector cosine search when embeddings and the index are available; otherwise the same corpus is ranked deterministically and the UI says which tier answered.
- Guidance is not a decision. It changes wording and what to ask next. Tests assert readiness, bands, overrides and safety routing are identical with and without it.
What each run costs
Every analysis stores its own accounting on the scope version: model, prompt and output tokens, end-to-end wall time, per-node wall time, retrieval tier and an estimated spend that names the rate card it used. Open any job and the numbers are on the page — no separate dashboard, no guessing.
Cost is always labelled an estimate: tokens come back from the API, the dollars are arithmetic on top of a documented rate assumption.
Guardrails that are not negotiable
- No diagnosis of faults.
- No price, price range or rate produced by AI.
- No automatic customer message — drafts are approved by a person.
- No safety claim: patterns are routed for professional attention, not assessed.
- No voice cloning; generated audio is labelled as generated.