Qontak Chat | Chatbot & AI | Autonomous AI Agent — Adj: Lead Protection
HEADER BLOCK
| Field | Value |
|---|---|
| PM | Dimas Fauzi Hidayat |
| PRD Version | 1.0 |
| Status | DRAFT |
| PRD Type | ADJUSTMENT |
| Epic | Pending — child Epic under BOT-4601 umbrella; add to README ## Jira Epics allow-set when created |
| Squad | BOT (Chatbot) |
| RFC Link | Pending — BE RFC required (close-decision guard) |
| Figma Master | Pending — designer adds (Lead protection subsection only; the guard itself has no UI) |
| Anchor | Yes — Autonomous AI Agent — ANCHOR |
| Labels | epic:qontak-chat | module:chatbot-ai | feature:ai-agent-lead-protection |
| Last Updated | 2026-07-23 |
Evidence provenance: every number in this PRD traces to the telesales quality-flag audit (Jun–Jul 2026); code anchors verified against
chatbotBE on 2026-07-23 (node_executions/nodes/mekari_qontak_chat/execute.rb,process_idle_rule_action.rb— the autonomous-agent stack only).
Table of Contents
- HEADER BLOCK
- 2. CONDITIONAL BLOCK: ADJUSTMENT CONTEXT
- 3. One-liner + Problem
- 4. Target Users + Persona Context
- 5. Non-Goals
- 6. Constraints
- 7. Scope Changes
- 8. Feature Changes
- 9. API & Webhook Behavior
- 10. System Flow + User Stories + ACs
- 11. Rollout
- 12. Observability
- 13. Success Metrics
- 14. Launch Plan & Stage Gates
- 15. Dependencies
- 16. Key Decisions + Alternatives Rejected
- 17. Open Questions
- PRD CHANGELOG
2. CONDITIONAL BLOCK: ADJUSTMENT CONTEXT
Parent Anchor PRD: ../autonomous-ai-agent-anchor.md
This adjustment covers: The close decision of the autonomous AI Agent for conversations
that show buying intent. Two chokepoints change: (1) the agent's
room-resolve action, (2) the Idle action when set to "Resolve
conversation". Adds an admin "Lead protection" config subsection
and protected-lead observability events.
Parent PRD still owns: Agent configuration (Profile / Capabilities / Routing), reply
generation and the AI Service contract, handover mechanics
(assign workers, round-robin), and all closes of conversations
WITHOUT buying intent — those flows are unchanged.
Reason for adjustment: The Jun–Jul 2026 telesales quality audit found 259 conversations
with explicit buying signals (price discussion, demo/compro
requests, submitted lead forms) closed by the bot without human
follow-up (see sources).
Scope boundary: Only the close decision at the two chokepoints above. No changes
to the AI Service (DSAI) request/response contract, no new reply
wording, no changes to human-initiated resolves.
3. One-liner + Problem
One-liner: Stop the autonomous AI Agent from closing conversations that show buying intent — force a human handover (or keep the room open) instead, so sales teams never lose a live lead to an automatic close.
Problem:
The agent decides on its own when to resolve a conversation, and nothing in the product distinguishes a lead discussing price, packages, or a demo from an ordinary resolved inquiry. In the audited period the bot closed 259 such conversations — including customers who had just submitted a lead form or asked for a company profile — and the idle timer closed leads that merely went quiet mid-negotiation. Code-grounded: no lead-qualification logic exists anywhere in the backend; resolve_room closes unconditionally (mekari_qontak_chat/execute.rb:147-156) and the idle path's only guard is "has the customer replied since" (process_idle_rule_action.rb:135-143).
4. Target Users + Persona Context
Personas inherited from the parent ANCHOR. Adjustment-specific notes:
| Persona | Role | Goal | Pain | Workaround |
|---|---|---|---|---|
| Primary — Sales / Telesales Agent | Human agent receiving handovers | Get every live lead in their inbox before it goes cold | Bot closes leads mid-negotiation; the agent never sees them | Manually trawling closed-room lists after the fact (the audit's Reclaim list is this workaround, done once) |
| Secondary — Org Admin | Configures the AI Agent | Turn on protection and route leads to the right team | No setting exists that protects leads from auto-close | Writing "always hand over" instructions into Profile → Guidance or Routing rules (WHEN Customer says → THEN Assign conversation) — unenforced; the model can still resolve |
5. Non-Goals
- No lead-scoring model or ML pipeline. The intent check is a binary buying-intent classification at close-time only — no scores, no persisted "lead grade".
- No CRM deal auto-creation. Handover delivers the conversation to a human; creating deals/tickets remains a separate existing agent action.
- No changes to the Ask Airene (RAG) answering path. This adjustment touches close decisions of the autonomous agent only.
- No change to closes of conversations without buying intent — spam, junk, and resolved support questions keep today's behavior, including idle-resolve.
- Not re-speccing the idle-action initiative. The
RESOLVE_AI_IDLEclose-reason split is delivered by ai-agent-idle-action; this PRD only consumes it (see §15).
6. Constraints
Platform: Same as parent — agent runtime (backend) + web admin (AI Agent settings).
Performance: Intent check adds ONE LLM classification call at close-decision time only
(never per message). p95 added latency at the close decision ≤ 2s.
On classifier timeout (> 5s) or error: fail-open — the close proceeds as
today and the failure is logged (see §16 D-3).
Backward compat: No schema change to existing rooms. New config lives in the existing
ai_agent parameters JSON (profile.lead_protection). Existing agents
without the key behave exactly as today.
Feature flag: ai_agent_lead_protection | default: OFF
Rollout note: Pilot on Qontak's own Telesales org (the audited org) before any customer org.
7. Scope Changes
Backend (close-decision guard, intent check, events) · Frontend (Lead protection subsection in the AI Agent editor) · Design (subsection layout — reuses the Assign-conversation selector pattern).
8. Feature Changes
Change ID: CHG-001 — Bot resolve of a buying-intent conversation becomes a handover
Change Type: Modified behavior
Page: N/A — agent runtime (no UI)
Page Intent: The agent decides to end a conversation it believes is finished
Before:
- The AI Agent's room-resolve action closes the room unconditionally
(mekari_qontak_chat/execute.rb:147-156, closed_reason hardcoded to RESOLVE).
259 buying-intent conversations were closed this way (incl. idle) in the audit.
After:
- With ai_agent_lead_protection ON: before executing the resolve, the backend runs a
buying-intent check on the recent conversation. Positive → the resolve is replaced
by a handover to the configured lead destination (auto / division / specific agent,
reusing the existing assign paths in execute.rb:92-143). Handover-disabled orgs →
the room is left open instead.
- Negative or errored check (fail-open) → the resolve proceeds as today.
| Element | Before | After |
|---|---|---|
| Bot resolve on buying-intent room | Room closes | Handover to lead destination (or held open) |
| Bot resolve on non-lead room | Room closes | Room closes (unchanged) |
| Close reason recorded | RESOLVE | Assign path reason for converted handovers |
Change ID: CHG-002 — Idle "Resolve conversation" is overridden for buying-intent rooms
Change Type: Modified behavior
Page: N/A — agent runtime (no UI)
Page Intent: The idle timer fires on a quiet conversation
Before:
- Idle action "Resolve conversation" closes the room after the configured wait time
(process_idle_rule_action.rb:157-165). The only guard is has_new_reply?; a lead
who paused to consider pricing is closed like any idle chat.
After:
- With ai_agent_lead_protection ON: when the idle timer fires with action "Resolve
conversation", the same buying-intent check runs first. Positive → the action is
executed as "Assign conversation" to the lead destination. Negative/error → resolve
proceeds as today.
- Idle actions "Assign conversation", "Follow up customers", and "None" are unchanged.
| Element | Before | After |
|---|---|---|
| Idle resolve on buying-intent room | Room closes | Assigned to lead destination |
| Idle resolve on non-lead room | Room closes | Room closes (unchanged) |
| Idle assign / follow-up / none | As configured | As configured (unchanged) |
Change ID: CHG-003 — "Lead protection" subsection in AI Agent settings → Profile
Change Type: Modified component (existing settings page gains a subsection)
Page: /bot-automation/ai-agent/{id} (AI Agent editor, Profile tab)
Page Intent: Admin configures how this agent behaves
Before:
- No lead-protection concept exists. The nearest autonomous-agent controls are
Profile → Guidance (free-text instruction, unenforced), Routing rules
(WHEN Customer says → THEN Assign conversation — reactive, not close-time),
and the Idle action selector.
After:
- New "Lead protection" subsection in the Profile tab (rendered only when the org has
the ai_agent_lead_protection flag): per-agent on/off toggle + lead handover
destination selector reusing the existing Assign-conversation pattern
(Auto / Division / Specific agent — same validation as AiAgentIdleActionForm).
- Default state for existing agents: toggle OFF until an admin enables it.
| Element | Before | After |
|---|---|---|
| Profile tab | Guardrails, Guidance, Tone, Idle action, … | Same + Lead protection subsection (flag-gated) |
| Handover destination | Only per idle-assign / routing config | Also configurable as the lead destination |
Figma: Pending — designer adds (reuse Assign-conversation selector pattern).
9. API & Webhook Behavior
| # | Behavior | Entity Affected | Triggered By | Expected Behavior | Failure Behavior |
|---|---|---|---|---|---|
| 1 | Buying-intent check at close decision | Room (close decision); result attached to the decision log | (a) AI Agent room-resolve action, (b) idle timer firing with action "Resolve conversation" — only when the org flag AND the agent toggle are ON | Backend LLM classification (existing internal Gpt::Completion path) runs on the recent transcript before the close executes. Positive → close converted to assign (or held open). Negative → close proceeds. Result + latency emitted as ai_agent_lead_intent_check. (RFC resolves: chokepoint placement per path, transcript window, prompt, per-room caching.) | Timeout (>5s) or error → fail-open: close proceeds, error captured on the event; no retry at close time |
| 2 | Lead protection configuration persistence | AI Agent configuration (parameters.profile.lead_protection) | Admin saves the Lead protection subsection | Existing agent update endpoint accepts the new optional profile key: lead_protection { enabled, assign_type (auto/division/agent), division_id?, agent_id? }. Backend-only — no AI Service re-sync needed | Validation error if enabled=true with assign_type division/agent but no id — same pattern as the Idle action form |
10. System Flow + User Stories + ACs
10.1. System Flow
Flow: AI Agent close decision (updated)
Type: System decision flow — delta on the close step of the autonomous conversation flow
1. Customer converses with the AI Agent — unchanged
2. Agent decides the conversation is finished (resolve action) OR idle timer fires
with action "Resolve conversation"
3. CHANGED: if lead protection is ON for this agent → run buying-intent check on the
recent transcript (one LLM call, ≤5s budget)
4. CHANGED: check positive → resolve is replaced:
4a. Lead destination configured → assign to it (auto / division / agent),
agent notified, room leaves bot control
4b. No lead destination configured (or assignment cannot complete) → room held
open (no close), no_destination event logged
5. CHANGED: check negative or errored (fail-open) → resolve proceeds as today
6. Room close/assign recorded — unchanged mechanics
📊 System Flow — Lead Protection Guard
graph TD
A[Bot resolve action OR idle timer: Resolve] --> B{Lead protection ON<br/>for this agent?}
B -- No --> Z[Resolve room - today's behavior]
B -- Yes --> C[Buying-intent check<br/>one LLM call, 5s budget]
C -- Error / timeout --> E[Fail-open: resolve room<br/>+ log error event]
C -- Negative --> Z
C -- Positive --> D{Lead destination<br/>configured?}
D -- Yes --> F[Assign to lead destination<br/>auto / division / agent]
D -- No --> G[Hold room open<br/>+ no_destination event]
F --> H[Event: lead_protection_triggered outcome=assigned]
G --> I[Event: lead_protection_triggered outcome=held_open]
10.2. User Stories
[LEAD-S01] — Bot resolve of a buying-intent conversation is converted to a handover
| User Story | As a Sales/Telesales Agent, I want conversations where the customer shows buying intent to reach my inbox instead of being closed by the bot, so that no live lead is lost to an automatic close. |
| Before State | The agent's room-resolve action closes the room unconditionally (execute.rb:147-156); 259 buying-intent conversations were closed this way in the audited period. |
| After Delta | With protection ON, a positive buying-intent check replaces the resolve with an assignment to the configured lead destination; negative or errored checks resolve as today. |
| Importance | Must Have |
| Mockup / Technical Notes | Design: N/A — backend behavior; handed-over rooms surface through the existing assignment UI. Data Fields: • profile.lead_protection.enabled (boolean) — admin input• profile.lead_protection.assign_type (enum auto/division/agent) — admin input• profile.lead_protection.division_id / agent_id (id, conditional) — admin input• intent_check.result (enum buying_intent/none) — backend classificationBefore-After Behavior: Bot-resolve on a buying-intent room previously closed it; after this story it lands in a sales agent's inbox. |
| Acceptance Criteria | — Happy Path — • AC-1: Given lead protection is ON and the customer's recent messages discuss price/packages/demo (e.g. "boleh dikirimkan detail paketnya"), when the AI Agent triggers its room-resolve action, then the room is NOT closed and is assigned to the configured lead destination, and ai_agent_lead_protection_triggered is emitted with outcome=assigned.• AC-2: Given lead protection is ON and the conversation shows no buying intent (e.g. a resolved OTP/support question), when the AI Agent triggers its room-resolve action, then the room closes exactly as today. • AC-3: Given the check is positive and no lead handover destination is configured for the agent, when the AI Agent triggers its room-resolve action, then the room is left open (not closed, not assigned) and ai_agent_lead_protection_no_destination is emitted.• AC-4: Given the lead destination is a division with no online agents, when a protected handover is attempted, then the existing assign queueing behavior applies and the room is not closed. — Error / Unhappy Path — • ERR-1: Given the buying-intent check times out (>5s) or errors, when the close decision runs, then the resolve proceeds as today (fail-open) and ai_agent_lead_intent_check is emitted with the error populated.— Permission Model — • CAN: system only (agent runtime) — no user-facing trigger • CANNOT: human agents' manual resolves are never intercepted • Unauthorized: N/A — backend behavior — UI States — • Loading/Empty/Error/Success: N/A — backend behavior; assignment surfaces via existing inbox UI |
Dependencies: None
[LEAD-S02] — Idle "Resolve conversation" is overridden for buying-intent rooms
| User Story | As a Sales/Telesales Agent, I want leads that go quiet to be assigned to me rather than auto-closed, so that I can follow up instead of losing them silently. |
| Before State | Idle action "Resolve conversation" closes any quiet room after the configured wait (process_idle_rule_action.rb:157-165); the only guard is has_new_reply?. |
| After Delta | With protection ON, idle-resolve first runs the buying-intent check; positive → the room is assigned to the lead destination instead of closed. |
| Importance | Must Have |
| Mockup / Technical Notes | Design: N/A — backend behavior. Data Fields: shares profile.lead_protection.* with LEAD-S01.Before-After Behavior: A quiet mid-negotiation lead was previously closed by the idle timer; after this story it is assigned to sales. |
| Acceptance Criteria | — Happy Path — • AC-1: Given lead protection is ON, the agent's Idle action is "Resolve conversation", and the room's transcript shows buying intent (e.g. the last exchange was a price objection), when the idle timer fires, then the room is assigned to the lead destination instead of resolved, and ai_agent_lead_protection_idle_override is emitted.• AC-2: Given lead protection is ON and the quiet room shows no buying intent, when the idle timer fires, then the room resolves exactly as configured today. • AC-3: Given the agent's Idle action is "Assign conversation", "Follow up customers", or "None", when the idle timer fires, then behavior is unchanged — the guard only intercepts "Resolve conversation". — Error / Unhappy Path — • ERR-1: Given the buying-intent check errors when the idle timer fires, then the idle resolve proceeds as configured (fail-open) and the error is captured on ai_agent_lead_intent_check.— Permission Model — • CAN: system only · CANNOT: manual resolves never intercepted · Unauthorized: N/A — UI States — • N/A — backend behavior |
Dependencies: [LEAD-S01] (shares the intent check and destination config)
[LEAD-S03] — Admin configures Lead protection in AI Agent settings
| User Story | As an Org Admin, I want to turn lead protection on per agent and choose where protected leads go, so that leads land with the right sales team. |
| Before State | No lead-protection setting exists anywhere in the AI Agent editor. |
| After Delta | Profile tab gains a flag-gated "Lead protection" subsection: per-agent toggle + lead handover destination (Auto / Division / Specific agent, same pattern as the Assign-conversation selector). |
| Importance | Should Have |
| Mockup / Technical Notes | Design: Pending — designer adds (Wulan; reuse the Assign-conversation selector pattern from AiAgentIdleActionForm.vue).Data Fields: profile.lead_protection.* (see LEAD-S01).Before-After Behavior: Admin previously had no lead-protection control; after this story it is a Profile-tab subsection. |
| Acceptance Criteria | — Happy Path — • AC-1: Given my org has the ai_agent_lead_protection flag, when I open AI Agent settings → Profile, then I see the Lead protection subsection with the toggle OFF by default.• AC-2: Given I enable the toggle and select assign type "Division" with a division, when I save, then the config persists and subsequent close decisions on this agent use it. • AC-3: Given I enable the toggle and select "Division" or "Specific agent" without choosing one, when I save, then I see the same required-selection validation as the Idle action form and the save is blocked. • AC-4: Given my org does NOT have the flag, when I open AI Agent settings → Profile, then the subsection is not rendered at all. — Error / Unhappy Path — • ERR-1: Given the save request fails (network/server), when I click Save, then the existing editor error toast shows and my inputs are preserved. — Permission Model — • CAN: Org Admin (same role that edits AI Agent settings today) • CANNOT: Agent/Supervisor roles without agent-edit permission • Unauthorized: subsection not rendered (matches editor-wide behavior) — UI States — • Loading: editor-standard skeleton • Empty: toggle OFF, destination selector hidden until enabled • Error: editor-standard toast on failed save • Success: "AI agent changes saved" toast (existing) |
Dependencies: [LEAD-S01] (consumes the config)
[LEAD-S04] — Protected-lead activity is visible in events and countable per org
| User Story | As an Org Admin (and as the BOT squad), I want to see how many leads protection saved and how it behaves, so that we can prove impact and tune precision. |
| Before State | A blocked-then-handed-over lead is indistinguishable from any other assignment; idle-closes are indistinguishable from bot-chosen closes (bare RESOLVE for both). |
| After Delta | The four §12 events make protection activity measurable per org; the idle/bot close-reason split itself arrives via ai-agent-idle-action (§15 dependency). |
| Importance | Should Have |
| Mockup / Technical Notes | Design: N/A — events/dashboard only; org-facing reporting is a later phase (§17 OQ-5). Before-After Behavior: Protection activity was previously invisible; after this story it is queryable per org. |
| Acceptance Criteria | — Happy Path — • AC-1: Given lead protection triggered on a room, when the decision completes, then exactly one ai_agent_lead_protection_triggered event exists for that decision with outcome, trigger, and destination populated.• AC-2: Given a week of pilot traffic, when the BOT dashboard is reviewed, then protected-lead count, intent-check error rate, and no_destination rate are all queryable per org. — Permission Model — • CAN: BOT squad (internal dashboards) · CANNOT: org users (this phase) · Unauthorized: N/A |
Dependencies: [LEAD-S01], [LEAD-S02]
Negative / Regression Guard Stories
| User Story | Importance | Acceptance Criteria |
|---|---|---|
| [LEAD-NEG-01] — Flag OFF means byte-for-byte today's behavior (from Non-Goal 4 + §6 flag) | Guard Rail | NEG-1: Given the ai_agent_lead_protection flag is OFF for the org (default), when the agent resolves any room or the idle timer fires, then behavior is identical to today — no intent check runs, no new events are emitted. |
| [LEAD-NEG-02] — Human resolves are never intercepted (scope boundary) | Guard Rail | NEG-1: Given a human agent manually resolves a room that shows buying intent, when the resolve executes, then it is never intercepted — the guard applies only to bot-initiated closes. |
| [LEAD-NEG-03] — Non-lead closes unchanged under flag ON (from Non-Goal 4) | Guard Rail | NEG-1: Given lead protection is ON, when the agent resolves spam/junk/support rooms with no buying intent, then close behavior and close reasons are unchanged. |
11. Rollout
Rollout type: Controlled rollout with flag
Feature flag: ai_agent_lead_protection | default: OFF
Rollout: Stage 1 → Internal QA (staging org + 1 production test org) — 1 week
Stage 2 → Qontak Telesales org (the audited org) — 2 weeks, flag ON
Stage 3 → Opt-in GA for sales/telesales-type orgs via flag
Backward compat: Yes — flag-OFF orgs see zero behavior change.
Migration: None. The new parameters key is written on first save of the Lead
protection config; absence of the key = protection off for that agent.
12. Observability
New Events:
| Event Name | Trigger | Properties |
|---|---|---|
ai_agent_lead_intent_check | Guard runs the buying-intent classification at a close decision | room_id, org_id, trigger (resolve_action/idle_rule), result, latency_ms, error (nullable) |
ai_agent_lead_protection_triggered | A bot resolve was converted to a handover (or hold-open) | room_id, org_id, trigger, outcome (assigned/held_open), destination (nullable) |
ai_agent_lead_protection_idle_override | Idle "Resolve conversation" overridden for a buying-intent room | room_id, org_id, idle_duration_config, outcome |
ai_agent_lead_protection_no_destination | Guard blocked a close but no lead handover destination is configured | room_id, org_id |
Dashboard owner: BOT squad
Review cadence: Weekly for the first 4 weeks after each stage, then monthly. Owner: PM (Dimas).
Alerts:
- intent-check error rate > 5% daily → Slack #bot-squad
- protected-leads count drops > 50% week-over-week while flag ON → investigate
- no_destination events > 10% of triggers → orgs misconfigured, CSM follow-up
13. Success Metrics
⭐ Primary KPI: Buying-intent conversations closed by the bot
Definition: Rooms with a positive buying-intent classification that end in a
bot-initiated close (resolve action or idle-resolve) without handover.
Baseline: 259 conversations / 7 weeks on the audited org (see sources).
Target: ≤ 10% of baseline rate within 30 days of Stage 2 flag ON.
- Handover rate for buying-intent conversations
Definition: triggered outcome=assigned ÷ positive intent checks.
Baseline: N/A — not measurable today (no intent signal exists).
Target: ≥ 95% (remainder = held_open rooms where no lead destination is configured).
- Guard precision (quality guard against inbox noise)
Definition: % of protected rooms judged "genuine lead" in a weekly manual sample of 30.
Baseline: N/A — new mechanism.
Target: ≥ 80% during Stage 2; below that, tune the classification prompt before Stage 3.
14. Launch Plan & Stage Gates
| Stage | Audience | Duration | Success Gate to Advance | Owner |
|---|---|---|---|---|
| 1 — Internal QA | Staging + 1 test org | 1 week | All ACs pass; intent-check p95 ≤ 2s; fail-open verified by forced classifier outage | BOT QA |
| 2 — Pilot | Qontak Telesales org | 2 weeks | Protected-lead count > 0 and trending with traffic; guard precision ≥ 80% on manual sample; zero regression reports on non-lead closes | PM (Dimas) |
| 3 — Opt-in GA | Sales/telesales-type orgs requesting it | Ongoing | Primary KPI ≤ 10% of baseline on pilot org; no_destination < 10% of triggers | PM + BOT |
15. Dependencies
| Dependency | Owning Team | Deliverable Needed | Blocking? |
|---|---|---|---|
ai-agent-idle-action (RESOLVE_AI_IDLE close-reason split) | BOT | The distinct idle close reason this PRD's reporting consumes to separate idle-closes from bot-chosen closes | NO — the guard ships without it; reporting degrades to event-based counting until it lands |
| Admin config UI design (Lead protection subsection) | Design (Wulan) | Figma frames for toggle + destination selector | NO — BE guard + events ship first; LEAD-S03 waits for design |
LLM availability for the intent check (existing internal Gpt::Completion path) | BOT (existing lib) | None new — reuses the pattern shipped for spam-gatekeeper | NO — fail-open on outage (§6) |
No DSAI dependency: the intent check is backend-owned by design (§16 D-1).
16. Key Decisions + Alternatives Rejected
16a — Decisions Made
| Date | Decision | Rationale |
|---|---|---|
| 2026-07-23 | D-1: Buying-intent detection is a backend-owned Gpt::Completion classification at the close chokepoints | Same pattern that replaced the DSAI classifier in spam-gatekeeper; avoids a DSAI contract; works identically for both chokepoints |
| 2026-07-23 | D-2: When no lead handover destination is configured (or assignment cannot complete), the guard still blocks the close and the room stays open | Safest for revenue — the lead stays visible in the inbox; skipping the guard would keep losing exactly the leads this PRD protects |
| 2026-07-23 | D-3: Fail-open on classifier error/timeout (close proceeds, failure logged) | An LLM outage must not freeze all conversation closes org-wide; the failure event keeps the gap measurable |
| 2026-07-23 | D-4: Intent check runs only at close decisions, never per message | Cost and latency control — one call per close attempt instead of one per inbound message |
16b — Alternatives Rejected
| Alternative | Why Rejected | Date |
|---|---|---|
| DSAI returns a buying-intent field in its reply contract | Hard dependency on the AI-Service team for a signal the backend can compute itself; DSAI contract changes have been slow/unreliable in past initiatives | 2026-07-23 |
| Keyword/regex-only intent detection | Misses paraphrase and slang ("ada yg under 1 juta kah", "200 bsa?") that dominate the audited transcripts | 2026-07-23 |
| Force-enable handover when the flag turns on | Silently changes another org setting; surprising side effect for admins | 2026-07-23 |
| Prompt-only fix (strengthen Profile → Guidance / Routing-rule instructions) | Already possible today and demonstrably insufficient — the audited org's model still chose to resolve; an unenforced instruction cannot be a guarantee | 2026-07-23 |
17. Open Questions
| # | Type | Question | Owner | Deadline |
|---|---|---|---|---|
| 1 | Risk | Intent-check false positives inflate the human inbox. Mitigation: precision gate ≥ 80% at Stage 2, prompt tuning before Stage 3, per-org flag off instantly. | PM (Dimas) | Stage 2 exit |
| 2 | Risk | Held-open rooms (agents with no configured lead destination) accumulate unattended. Mitigation: no_destination event + Stage 3 gate < 10%; recommend those orgs configure a lead destination or keep the flag OFF. | PM (Dimas) | Stage 3 entry |
| 3 | Assumption | The audited org's buying-signal patterns (Bahasa Indonesia telesales) generalize to other sales-type orgs; the classification prompt is language-configurable if not. | BOT Eng | Stage 3 entry |
| 4 | Open Question | Should protection also cover the legacy AI-Assist resolve path (non-autonomous orgs)? Deferred — measure demand after Stage 3. | PM (Dimas) | 2026-09-30 |
| 5 | Open Question | Rupiah value per protected lead for the ROI/impact report (ties into ai-agent-impact-report). | PM (Dimas) | 2026-09-30 |
PRD CHANGELOG
| Version | Date | By | Section | Type | Summary |
|---|---|---|---|---|---|
| 1.0 | 2026-07-23 | Claude | All | CREATED | Adjustment PRD created from the Jun–Jul 2026 telesales quality audit (259 qualified leads auto-closed) |