Portfolio verification — September 14, 2026 rental — captured test output; local paths anonymized. > rental-inquiry-automation@1.0.0 test > npm run test:reliability > rental-inquiry-automation@1.0.0 test:reliability > node --test tests/reliability/*.test.js ◇ injected env (0) from .env // tip: ◈ encrypted .env [www.dotenvx.com] [Intent] Unrecognized intent: "NONSENSE_INTENT" — defaulting to ESCALATE ✔ strict mode: prompt includes "Does NOT include" tightening on TOUR_REQUEST (668.110459ms) ✔ strict mode: prompt frames ESCALATE as a positive choice, lists access codes (0.344875ms) ✔ strict mode: includes few-shot examples covering access codes → ESCALATE (0.314917ms) ✔ strict mode: includes the history-contamination instruction WHEN history is provided (0.21675ms) ✔ strict mode: omits the contamination instruction when there is no history (0.264375ms) ✔ flag OFF: legacy prompt is sent unchanged (no regression) (0.312125ms) ✔ strict mode: classifier returns ESCALATE when LLM returns ESCALATE (0.238ms) ✔ strict mode: invalid LLM response defaults to ESCALATE (0.312625ms) ✔ buildStrictClassifierPrompt directly: covers all required Layer B test cases (0.607416ms) [AutoReply] Processing messageId=msg-rent threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "What's the rent?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: PRICING_QUESTION | Follow-up: false [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-tour threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "I'd like to schedule a tour Saturday" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-apply threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "How do I apply?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [Intent] Deterministic pre-check → APPLICATION_REQUEST [AutoReply] AI Intent: APPLICATION_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-pets threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "Do you allow pets?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] Injecting 1 knowledge base entries [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-section8 threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "do you take Section 8?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-access threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "May I have the access code?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: ESCALATE | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Access code is not stored in property_data or knowledge_base; cannot answer. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-sqft threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "What's the square footage?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Square footage is not present in property_data. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-safe threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "Is this a safe neighborhood?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Compliance: cannot make subjective statements about neighborhoods. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-approval threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "Will I get approved?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Compliance: cannot promise or imply application approval. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-floors threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "What kind of flooring?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Grounding verifier blocked reply. Unsupported claims: - "hardwood floors throughout" (source: property_data.flooring) — property_data.flooring does not exist [AutoReply] Blocked reply was: The unit features hardwood floors throughout. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-compliance threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "What's the rent?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Grounding verifier blocked reply. Compliance violations: - "great neighborhood for families" — subjective neighborhood claim with no source; also implicates protected class (family status) [AutoReply] Blocked reply was: The rent is $1850/mo. This is a great neighborhood for families. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-rent-pass threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "rent?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: PRICING_QUESTION | Follow-up: false [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-utils threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "who pays utilities?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-sample-access threadId=thread-id [AutoReply] From: TEST TEST <1gy8kn3p674bzi1d15upepkb39p@convo.zillow.com> | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "may I please have the acess code to access the building?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: true [AutoReply] BLOCKED — Responder escalated: Access code is not stored anywhere in the data. [AutoReply] Escalation sent to operator@example.com for lead: TEST TEST (subject: URGENT: Zillow Lead Requires Immediate Attention — TEST TEST) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-qvr025 threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "Could I have the lockbox code to access the building. I am currently passing by the area." [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Lockbox code is not in property_data, KB, or training_rules; lead is on-site. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-jq21gb threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "I'm at the property — how do I get in?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: On-site lead asking for entry instructions; entry process not in data. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-7fzulh threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "I'm in the driveway, what's the code?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: On-site lead asking for code; on-site lead is an escalation signal. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-ss6g7t threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "How does the self-guided tour work?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Booking flow is not documented in property_data, KB, or training_rules; cannot describe the process. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-yl0ffa threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "What happens after I book?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Post-booking flow not in data; cannot describe what happens. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=msg-tour-flow threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "How does the self-guided tour work?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] Injecting 1 knowledge base entries [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-tour-sat threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "I'd like to schedule a tour for Saturday" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent-1 threadId=thread-id [AutoReply] Processing messageId=msg-tl59vd threadId=thread-id [AutoReply] From: lead@example.com | Subject: Re: 123 Example Street info [AutoReply] Lead message extracted: "May I have the access code?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: Access code is not stored in property_data, kb, or training_rules. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" ✔ ANSWER: rent question with property_data.rent populated → reply sent, contains rent (18.33175ms) ✔ ANSWER: tour request with property_data.calendlyLink populated → reply includes link (4.483667ms) ✔ ANSWER: application question with property_data.applicationLink populated → reply includes link (2.101584ms) ✔ ANSWER: pet question with KB pet-policy entry present → reply cited to kb. (6.230292ms) ✔ ANSWER: training rule for Section 8 → reply cited to training_rule. (2.173666ms) ✔ ESCALATE: access-code request → no lead reply, escalation email sent (3.187417ms) ✔ ESCALATE: missing field (sqft null) → escalate even if classifier says GENERAL_QUESTION (1.122625ms) ✔ ESCALATE (compliance): subjective neighborhood question → no answer, even though we COULD make one up (3.044ms) ✔ ESCALATE (compliance): "will I get approved?" → no approval promise (1.362709ms) ✔ VERIFIER: fabricated claim with bogus source → reply blocked, escalation forced (2.103625ms) ✔ VERIFIER: ungrounded compliance violation in reply text → blocked even when claims look fine (1.410042ms) ✔ VERIFIER: fully grounded reply passes → reply sent (3.401333ms) ✔ TRAINING PATHWAY: rule added to Firestore is reflected in the responder context on the next message (2.432958ms) ✔ SAMPLE: access-code question with prior Calendly send in thread → ESCALATE, no Calendly sent (4.722542ms) ✔ LOOPHOLE: lockbox-code request from on-site lead (the actual failure) → ESCALATE, no Calendly (1.992875ms) ✔ LOOPHOLE: "I'm at the property — how do I get in?" → ESCALATE (on-site signal) (4.419375ms) ✔ LOOPHOLE: "I'm in the driveway, what's the code?" → ESCALATE (on-site signal) (0.88575ms) ✔ LOOPHOLE: "How does the self-guided tour work?" with no process info in data → ESCALATE (2.374625ms) ✔ LOOPHOLE: "What happens after I book?" with no booking-flow data → ESCALATE (1.900208ms) ✔ LOOPHOLE (positive case): "How does the self-guided tour work?" WITH a KB process entry → ANSWER citing kb. (2.103ms) ✔ LOOPHOLE (regression): normal tour request "schedule a tour Saturday" with calendlyLink → ANSWER (unchanged) (0.519ms) ✔ LOOPHOLE (regression): "May I have the access code?" → ESCALATE (Sample case still escalates) (0.418791ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started ✔ structured mode parses well-formed JSON into reply + claims (3253.743041ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Grounding JSON parse failed — escalating. Raw: this is not json at all [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started ✔ structured mode strips ```json fences before parsing (2.970709ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Verifier] Failed — defaulting to FAIL (escalate): econn timeout [Verifier] Failed — defaulting to FAIL (escalate): Unexpected token 'o', "not json" is not valid JSON ✔ structured mode honors escalate=true (1.023625ms) ✔ structured mode honors rule_triggered=true (0.803709ms) ✔ structured mode escalates on malformed JSON instead of sending unverified text (1.606334ms) ✔ plain-text mode still works when useGroundingClaims is false (no regression) (0.895875ms) ✔ plain-text mode still escalates on bare ESCALATE token (0.629583ms) ✔ verifyClaims short-circuits to PASS only when BOTH claims and reply are empty (0.461833ms) ✔ verifyClaims returns PASS when verifier model says pass (0.304417ms) ✔ verifyClaims returns FAIL with unsupported claims listed (0.326917ms) ✔ verifyClaims defaults to FAIL when verifier itself errors (network/parse) (0.273625ms) ✔ verifyClaims defaults to FAIL when verifier returns malformed JSON (0.222542ms) ✔ rejection-language blacklist (REJECTION_PHRASES / containsRejection) has been removed from autoReply.js (0.24775ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started ✔ flag ON: prompt has all three contract sections in order (A → B → C) (3244.800584ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started ✔ flag ON: Section A states the two-option contract and treats uncertainty as escalation (2.990292ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Contract] JSON parse failed — escalating. Raw: this is not JSON at all [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started ✔ flag ON: Section B has categorical NEVER and ALWAYS lists, no topic enumerations (0.80375ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started ✔ flag ON: Section C declares the new JSON schema with decision/reasoning/claims/escalation_reason (0.644ms) [Gemini] Failed to fetch live training rules, using base prompt only: Unable to detect a Project Id in the current environment. To learn more about authentication and Google APIs, visit: https://cloud.google.com/docs/authentication/getting-started ✔ flag ON: prompt does NOT contain old enumeration-style guidance or rejection language (0.771667ms) ✔ flag OFF: legacy responder prompt is used unchanged (no regression) (0.940917ms) ✔ flag ON: ESCALATE decision flows through to needsEscalation=true with escalationReason populated (1.008416ms) ✔ flag ON: ANSWER decision flows through to a non-empty reply with claims (0.634791ms) ✔ flag ON: malformed JSON from responder forces escalation (does not fall through to plaintext) (0.700416ms) ✔ Section A: process-description clause is present (closes "describe how booking works" loophole) (0.545042ms) ✔ Section A: asked-X-answered-Y substitution clause is present (0.711542ms) ✔ Section A: on-site escalation signal clause is present (1.600708ms) ✔ Section A: new clauses appear inside Section A (before Section B begins) (0.785167ms) ✔ flag OFF: new Section A clauses are NOT injected into the legacy responder prompt (0.53825ms) ✔ flag ON: ANSWER decision with empty reply forces escalation (0.428834ms) [AutoReply] Processing messageId=m-rent threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Whats the rent on this place?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — PROPERTY_NOT_READY_TO_LIST: 123 Example Street, Example City, TX 00000 is marked "Acquired — not ready to list" — agent did not consult responder/KB/rules. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: [Property Not Ready] Lead inquiry on 123 Example Street, Example City, TX, 00000) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=m-tour threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I schedule a tour Saturday?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — PROPERTY_NOT_READY_TO_LIST: 123 Example Street, Example City, TX 00000 is marked "Acquired — not ready to list" — agent did not consult responder/KB/rules. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: [Property Not Ready] Lead inquiry on 123 Example Street, Example City, TX, 00000) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-code threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "May I have the access code?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — PROPERTY_NOT_READY_TO_LIST: 123 Example Street, Example City, TX 00000 is marked "Acquired — not ready to list" — agent did not consult responder/KB/rules. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: [Property Not Ready] Lead inquiry on 123 Example Street, Example City, TX, 00000) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-tour-ok threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour Saturday" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-norm threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "What is the rent?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: PRICING_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: rent missing from property_data [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-rented threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Hey is this still available?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — PROPERTY_RENTED: 123 Example Street, Example City, TX 00000 is marked "Not available" (rented) — agent did not consult responder/KB/rules. [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: [Property Rented] Lead inquiry on 123 Example Street, Example City, TX, 00000) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-not-ready-email threadId=t [AutoReply] From: TEST | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Is this property still on the market?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — PROPERTY_NOT_READY_TO_LIST: 123 Example Street, Example City, TX 00000 is marked "Acquired — not ready to list" — agent did not consult responder/KB/rules. [AutoReply] Escalation sent to operator@example.com for lead: TEST (subject: [Property Not Ready] Lead inquiry on 123 Example Street, Example City, TX, 00000) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-rented-email threadId=t [AutoReply] From: TEST | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I book a tour Saturday?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — PROPERTY_RENTED: 123 Example Street, Example City, TX 00000 is marked "Not available" (rented) — agent did not consult responder/KB/rules. [AutoReply] Escalation sent to operator@example.com for lead: TEST (subject: [Property Rented] Lead inquiry on 123 Example Street, Example City, TX, 00000) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" ✔ Acquired-not-ready: any inquiry about it ESCALATES, responder never called (23.145667ms) ✔ Acquired-not-ready: tour request still escalates (state overrides intent) (1.105584ms) ✔ Acquired-not-ready: access-code question escalates with PROPERTY_NOT_READY_TO_LIST (not the usual "no data" reason) (2.158583ms) ✔ Availability flipped from Acquired → Available Now: same property, next inquiry → agent runs normally (2.08625ms) ✔ Acquired flag OFF: agent does NOT short-circuit on "Acquired — not ready to list" value (3.847667ms) ✔ Rented property: lead inquiry ESCALATES with PROPERTY_RENTED, responder never invoked (3.500708ms) ✔ Escalation email for PROPERTY_NOT_READY_TO_LIST has the right subject + body (0.870625ms) ✔ Escalation email for PROPERTY_RENTED has the right subject + body (1.047042ms) ✔ loadProperties: reads Firestore fresh on every call — no in-process cache (1.239041ms) ✔ PATCH validation — availability rejects empty (1.476542ms) ✔ PATCH validation — "Acquired" gated behind PROPERTY_NOT_READY_STATE_ENABLED (0.252542ms) ✔ PATCH validation — "Not available" accepted always (no flag gate) (0.142792ms) ✔ PATCH validation — active is coerced to a real boolean (avoid "false" string truthiness) (0.138084ms) [AutoReply] Processing messageId=msg-sample-access threadId=thread-id [AutoReply] From: TEST TEST <1gy8kn3p674bzi1d15upepkb39p@convo.zillow.com> | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "may I please have the acess code to access the building?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: true [AutoReply] BLOCKED — Tour preflight guard rejected: classifier returned TOUR_REQUEST but message does not explicitly request a tour. [AutoReply] Escalation sent to operator@example.com for lead: TEST TEST (subject: URGENT: Zillow Lead Requires Immediate Attention — TEST TEST) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" ✔ Sample Cir failure case — both flags ON → escalates, no Calendly sent (22.782208ms) ✔ filter: scope.type="all" → applies to any matched property (3.433917ms) ✔ filter: scope.type="all" → applies to first-touch with no property match (1.362084ms) ✔ filter: scope.type="subset", [P1,P2] → applies to P1 and P2, NOT P3 (0.512208ms) ✔ filter: scope.type="single", [P1] → applies to P1 only (0.207209ms) ✔ filter: rule with no scope field → treated as "all" (backwards compat) (0.558166ms) ✔ filter: subset rule with one stale propertyId → logs warning, still applies to a non-stale matching property (1.0955ms) ✔ filter: single rule with stale propertyId → does not apply (cleaned ids[] is empty) (1.903541ms) ✔ filter: flag OFF → returns rules unchanged regardless of scope (1.67275ms) ✔ filter: all stale single rule does not crash, returns [] (0.615708ms) ✔ validate: flag OFF → returns { ok:true, scope:null } regardless of input (0.738667ms) ✔ validate: flag ON, missing scope → defaults to {type:"all", propertyIds:[]} (0.594875ms) ✔ validate: flag ON, scope.type="all" with propertyIds populated → rejected (1.191125ms) ✔ validate: flag ON, scope.type="single" with 0 selected → rejected (0.463041ms) ✔ validate: flag ON, scope.type="subset" with only 1 selected → rejected (0.319ms) ✔ validate: flag ON, scope.type="subset" with 0 selected → rejected (0.59675ms) ✔ validate: flag ON, scope.type="bogus" → rejected (0.332ms) ✔ validate: flag ON, propertyId that does not exist → rejected (0.326583ms) ✔ validate: flag ON, all referenced propertyIds exist → ok with normalised scope (0.612417ms) ✔ validate: flag ON, propertyIds with whitespace-only entries → those entries are stripped (0.756292ms) [AutoReply] Processing messageId=m-tour-7b21 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-kvq8 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour. Please let me know what times are available for this coming Monday " [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-1iqn threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour at 5pm tomorrow" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-w48v threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I tour at 3pm on Saturday?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-dg86 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "What times are available on Sunday?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-list threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Is the property open for tours on weekends?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-11y1 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "When can I come see it?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-t4i4 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I come by today?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-iqr9 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I want to see the place" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-32c7 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I tour at 9am" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-mduo threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Are there evening slots?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-tour-lipp threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "What's the soonest tour I can do?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-no-link threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — Responder escalated: property_data.calendlyLink is missing — cannot route the lead to a booking page [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-no-link-2 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I tour Saturday at 2pm?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — Responder escalated: no calendlyLink configured for this property [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-verifier-pass threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I tour at 5pm tomorrow?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-verifier-block threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Can I tour at 5pm tomorrow?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — Grounding verifier blocked reply. Unsupported claims: - "5pm tomorrow is open" (source: property_data.availability) — availability field does not contain time-slot data [AutoReply] Blocked reply was: Yes, 5pm tomorrow is open. https://calendly.com/example-mgmt/sample-self-guided-tour [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-regression-code threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "May I have the access code?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: ESCALATE | Follow-up: false [AutoReply] BLOCKED — Responder escalated: access code not stored [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-regression-rent threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "What's the rent?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: PRICING_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: rent not in property_data [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-regression-safety threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Is this a safe neighborhood?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: GENERAL_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: cannot make subjective neighborhood claims [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-regression-apply threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "How do I apply?" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [Intent] Deterministic pre-check → APPLICATION_REQUEST [AutoReply] AI Intent: APPLICATION_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t [AutoReply] Processing messageId=m-flag-off threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t ✔ Prompt — useTourLinkAsAnswer=true: clause appears in Section A (6.70525ms) ✔ Prompt — useTourLinkAsAnswer=false: clause does NOT appear (0.204709ms) ✔ Prompt — useTourLinkAsAnswer undefined: clause does NOT appear (default-safe) (0.136875ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "I would like to schedule a tour" (18.644167ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "I would like to schedule a tour. Please let me know what tim" (4.234042ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "I would like to schedule a tour at 5pm tomorrow" (5.243083ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "Can I tour at 3pm on Saturday?" (2.604875ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "What times are available on Sunday?" (1.8865ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "Is the property open for tours on weekends?" (0.71225ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "When can I come see it?" (3.603291ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "Can I come by today?" (1.435166ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "I want to see the place" (0.77ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "Can I tour at 9am" (2.526834ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "Are there evening slots?" (2.082208ms) ✔ Wiring — phrasing ships the link + self-guided mention + no time-echo: "What's the soonest tour I can do?" (1.958375ms) ✔ No calendlyLink: tour request still escalates (responder returns ESCALATE) (1.519666ms) ✔ No calendlyLink: specific-time tour request still escalates (0.769667ms) ✔ Verifier passes: ANSWER + claim sourced to property_data.calendlyLink → reply ships (2.673791ms) ✔ Verifier blocks: ANSWER fabricates availability ("5pm is open") → escalation forced (0.932833ms) ✔ Regression — access-code request still escalates (contract holds) (0.534791ms) ✔ Regression — rent question on null rent still escalates (0.509375ms) ✔ Regression — subjective neighborhood question still escalates (compliance) (0.956709ms) ✔ Regression — application request with applicationLink still answers normally (1.074042ms) ✔ Wiring with TOUR_LINK_AS_ANSWER_ENABLED=false: responder answer still ships (the flag affects PROMPT content, not pipeline shape) (0.97725ms) [Preflight] Guard call failed — failing closed (NO): econn timeout ✔ guard returns YES for explicit tour request (13.127875ms) ✔ guard parses YES with trailing punctuation/whitespace (0.315083ms) ✔ guard returns NO for the access-code message (the actual failure) (0.160875ms) ✔ guard returns NO for "I'm at the property, how do I get in" (0.126625ms) ✔ malformed response (not YES/NO) → NO (fail closed) (3.399625ms) ✔ "MAYBE" response → NO (0.22025ms) ✔ empty response → NO (0.288958ms) ✔ LLM call throws (network/timeout) → NO with error attached (0.680875ms) ✔ "YES" prefixed prose ("YES, the lead is asking…") → NO (strict parsing) (0.197583ms) ✔ identical message twice hits cache (no second LLM call) (0.219375ms) ✔ different messages do not collide in cache (1.219167ms) ✔ prompt asks for one-word YES/NO and lists access-code as a NO case (0.621041ms) ✔ prompt does NOT include conversation history (history-contamination guard) (0.604209ms) ◇ injected env (0) from .env // tip: ⌘ multiple files { path: ['.env.local', '.env'] } [AutoReply] Processing messageId=m-pipeline threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "What is the rent for this property?" [AutoReply] Stripped Zillow profile blob — anchor="Reply to Send Application" bytesRemoved=434 [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: PRICING_QUESTION | Follow-up: false [AutoReply] BLOCKED — Responder escalated: rent not in property_data [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "escalate" [QuestionTracker] New pattern created: "escalate" [AutoReply] Processing messageId=m-flagoff threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "What is the rent for this property? Reply to TEST Send Application You can also reply directly to th" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [Intent] Deterministic pre-check → APPLICATION_REQUEST [AutoReply] AI Intent: APPLICATION_REQUEST | Follow-up: false [AutoReply] BLOCKED — Responder escalated: no rent [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-strip-1 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour." [AutoReply] Stripped Zillow profile blob — anchor="Reply to Send Application" bytesRemoved=434 [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — Responder escalated: mock [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [AutoReply] Processing messageId=m-strip-2 threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "Yes Saturday works" [QuestionTracker] New pattern created: "[]" [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] BLOCKED — Responder escalated: mock [AutoReply] Escalation sent to operator@example.com for lead: lead@example.com (subject: URGENT: Zillow Lead Requires Immediate Attention — lead@example.com) [QuestionTracker] Classified topic: "[]" [QuestionTracker] New pattern created: "[]" [AutoReply] Processing messageId=m-compliance threadId=t [AutoReply] From: lead@example.com | Subject: Re: TEST is requesting information about 123 Example Street, Example City, TX, 00000 [AutoReply] Lead message extracted: "I would like to schedule a tour." [AutoReply] Stripped Zillow profile blob — anchor="Reply to Send Application" bytesRemoved=434 [AutoReply] Regex address: (none) [AutoReply] Firestore match: 123 Example Street, Example City, TX 00000 [AutoReply] AI Intent: TOUR_REQUEST | Follow-up: false [AutoReply] Reply sent: messageId=sent threadId=t ✔ stripZillowProfile — Taylor-style: tour request preserved, blob removed (576.135167ms) ✔ stripZillowProfile — Jordan-style: multi-sentence preserved (0.329625ms) ✔ stripZillowProfile — plain reply with no blob: unchanged (0.165125ms) ✔ stripZillowProfile — natural-language "move in" without Zillow date pattern: NOT stripped (default-safe) (0.1715ms) ✔ stripZillowProfile — only-blob message: placeholder is used (0.176417ms) ✔ stripZillowProfile — earliest anchor wins when multiple appear (0.154791ms) ✔ stripZillowProfile — Fair Housing reminder alone (no "Reply to" preamble) (0.151541ms) ✔ stripZillowProfile — "You can also reply directly to this email" anchor on its own (0.203ms) ✔ stripZillowProfile — empty / null / non-string input: returns input unchanged, no crash (0.200625ms) ✔ stripZillowProfile — reply that quotes a prior email containing the blob: strips at earliest anchor anyway (0.225ms) ✔ extractLeadMessage — flag OFF: returns { cleaned, stripInfo:null } even with full Zillow blob (0.763125ms) ✔ extractLeadMessage — flag ON: strips the blob from the HTML-cleaned output (1.030292ms) ✔ extractLeadMessage — flag ON, no Zillow blob in input: stripInfo stays null (0.377875ms) ✔ Pipeline integration — flag ON: responder/classifier/verifier prompts contain CLEANED message only (4.643084ms) ✔ Pipeline integration — flag OFF: profile data DOES reach the prompts (regression baseline) (1.275917ms) ✔ Pipeline integration — inbound_strip_log row written exactly when strip occurs (1.100125ms) ✔ Compliance regression — responder reply NEVER mentions credit score / income / Fair Housing, even when inbound contained them (0.789875ms) ℹ tests 146 ℹ suites 0 ℹ pass 146 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 3363.741375