Qontak | Chatbot | AI Agent — Qontak Action — Released Actions (as-built)
REVERSE / as-built PRD. Documents Qontak-native AI Agent actions already shipped in code (verified against
chatbotBE +chatbot-feFE, 2026-06-17), reformatted into the standard Qontak PHASE structure. Every load-bearing claim citesfile:lineor a commit/Jira key. This is a record of shipped behavior + its gaps, not a plan for new work.
HEADER BLOCK
| Field | Value |
|---|---|
| PM | Dimas Fauzi Hidayat |
| PRD Version | 2.3 |
| Status | SHIPPED (as-built record) |
| PRD Type | PHASE (reverse / as-built) |
| Epic | BOT-3476 · BOT-3496 · BOT-3662 |
| Squad | BOT — Chatbot & AI Squad |
| RFC Link | N/A — as-built documentation |
| Figma Master | N/A — backend actions; legacy picker has no net-new UI |
| Anchor | Yes — Qontak Action — ANCHOR |
| Labels | epic:qontak-chatbot | module:ai-agent | feature:qontak-action |
| Last Updated | 2026-06-17 |
Status values:
DRAFT→READY→BUILD→SHIPPED. This doc records SHIPPED behavior.
⚠️ Reformat Flag Summary
Group A fills applied (v2.1): stories deepened (Permission Model + 4 UI States + Data Fields on every story; strict-Gherkin Guard Rail), System Flow diagram added, Observability spec'd as recommended instrumentation (+ alerts + cadence), Success Metrics targets proposed. Remaining flags are as-built / runtime-DB in nature — to confirm during the section-by-section runthrough:
| Section | Gap | Impact |
|---|---|---|
| 11. Observability | Events are recommended, not yet implemented | Adoption/reliability not measurable until instrumentation lands |
| 12. Success Metrics | Targets are proposed (confirmed in review), pending Mixpanel instrumentation | No committed baseline until events land |
Table of Contents
- HEADER BLOCK
- Reformat Flag Summary
- 2. CONDITIONAL BLOCK: PHASE CONTEXT
- 3. One-liner + Problem
- 4. Target Users + Persona Context
- 5. Non-Goals
- 6. Constraints
- 7. Feature Changes
- 8. API & Webhook Behavior
- 9. System Flow + User Stories + ACs
- 10. Rollout
- 11. Observability
- 12. Success Metrics
- 13. Launch Plan & Stage Gates
- 14. Dependencies
- 15. Key Decisions + Alternatives Rejected
- 16. Open Questions
- PRD CHANGELOG
2. CONDITIONAL BLOCK: PHASE CONTEXT
| Field | Detail |
|---|---|
| Anchor PRD | Qontak Action — ANCHOR |
| Phase Number | Not a sequential phase — an as-built catalog of Qontak-native actions under the Qontak Action initiative |
| Phase Goal | Document every Qontak-native AI Agent action already shipped, its mechanism, auth, gating, and the frontend-exposure gaps — as the accurate baseline for the initiative |
| Prior phases | CRM actions shipped Feb 2026 (BOT-3476 / BOT-3496 / BOT-3662). The mekari_qontak_chat executor (assign/resolve/tag) landed Mar–May 2026 (2796c8c73, a72ddfea3). |
| This phase | As-built record of 4 CRM actions (company token) + 3 chat actions (internal workers), reconstructed from the repos |
| Deferred to next | Closing the FE-exposure gap (Update Deal + the 3 chat actions); Send Attachment (own PRD); the prototype-only labels with no executor |
| Cross-phase deps | Shared AI Agent action framework — AiAgentAction / AiAgentTool models + node_type_registry.rb (GROUP map) routing mekari_qontak_crm and mekari_qontak_chat → executors. Must remain stable. |
3. One-liner + Problem
One-liner: The Qontak AI Agent can already execute Qontak-native operations mid-conversation — CRM writes (deals, tickets) via the company token, and conversation ops (assign, resolve, tag) via internal workers.
Problem: The Qontak Action initiative was split out of the broad "Mekari Action" anchor (2026-06-17) and never had its own PRD — the actions were built incrementally without one source of truth, so what's actually shipped (and what's merely exposed) was unclear. This as-built PRD records the live behavior, its company-token-vs-internal-worker auth split, and the gap between shipped executors and the legacy action picker. For full initiative context, see the Qontak Action ANCHOR.
4. Target Users + Persona Context
| Persona | Role | Goal | Pain | Workaround |
|---|---|---|---|---|
| Primary — CS Ops Lead / Bot Manager | Customer-side bot owner who configures the AI Agent in Qontak Chatbot | Let the agent perform Qontak operations (open a deal/ticket, tag, assign, resolve) mid-conversation without a human or a hand-built flow | Only 3 of the shipped actions appear in the legacy action picker; Update Deal + the chat actions aren't selectable there despite working backends | Build a flow-builder node, or rely on the v2 capability agent's DB-registered tools, or escalate |
| Runtime actor — AI Agent (executes the action) | The function-calling agent during a live conversation | Call the right Qontak-native action when the conversation calls for it | — (executes whatever tools are registered for the org) | — |
(Full persona background: see ANCHOR. Auth + gating: Section 6.)
5. Non-Goals
- Not introducing new actions — this PRD documents already-shipped behavior; it adds no capability.
- Not changing the auth model — company token (CRM) and internal workers (chat) are recorded as-is.
- Send Attachment action — tracked by its own PRD (phase-4-send-attachment-action.md); excluded here.
- Mekari-product and third-party actions — owned by the Mekari Action (HMAC) and Native Integration (OAuth) initiatives, not this one.
- Resolving the legacy-picker vs v2-capability frontend consolidation — that decision is its own forward work (flagged in Section 16), not documented as shipped here.
- Prototype-only labels with no executor — none remain in scope; all 7 documented actions have backends.
6. Constraints
| Field | Value |
|---|---|
| Platform | Configuration — Qontak web app. Runtime — the AI Agent function-calls actions during a conversation on any supported channel. |
| Auth — CRM actions | Qontak CRM company token (qontak_crm_company_token, bearer). Stored encrypted in organization_connection.auth_data (code: '__qontak_crm_company_token'); injected as Authorization: Bearer; refreshed on 401 via POST /api/v3.1/teams/company_token, fallback env QONTAK_CRM_API_KEY (X-Crm-Api-Key). Source: crm_http_client.rb:68-160. |
| Auth — Chat actions | Internal — operate on the org's own Room (resolved by channel_room_id + organization_id) and enqueue Sidekiq workers; no external API/token. Source: mekari_qontak_chat/execute.rb:39-41,93-160. |
| Feature flag | ai_agent_action (org) | default: OFF — enabled per account by ops; rollout_ai_agent_action (system preference) | default: OFF — gradual rollout. Legacy-picker visibility = ai_agent_action ON, OR (rollout_ai_agent_action ON + the relevant billing component). api action gated by ai_agent_action_api. Source: chatbot-fe/modules/ai-agent/composables/useActionFormVisibility.ts:56-111. |
| Plan / billing component (per action) | Billing is per action component, mapped to the Mekari suite the action belongs to (active components in chatbot/app/core/repositories/organization_features/feature_detail.rb:6-13):• Create / Update Deal → CP-QONTAKCRM-2025-0005 (CRM Deal) → Sales Suite• Create / Update Ticket → CP-QONTAKCRM-2025-0002 (CRM Ticket) → Service Suite• Base AI Agent entitlement: CP-QONTAKCHAT-2025-0028 (BOT AI Agent), CP-QONTAKCHAT-2026-0012 (AI Agent Active), CP-QONTAKCHAT-2026-0009 (AI Agent API Integration)• Chat actions (assign / resolve / tag) have no separate CRM component — they inherit the base AI Agent entitlement. Subscription is matched by component code on the org's active_components_summary (get_subscription.rb:20-24). |
| Performance / data limits | N/A — backend actions; inherit Qontak CRM API + platform limits. No Qontak-Action-specific latency/size/quota constraints. |
| Registry gating | node_registries.enabled per action (DB). Source: chatbot/app/models/node_registry.rb:29. |
| Read/write | Configure — builder roles that can edit AI Agent config (Admin / Bot Manager). Trigger — the AI Agent at runtime. Customers cannot configure or trigger. |
7. Feature Changes
As-built exposure surface — describes how the shipped actions are reached, and the gap.
Change ID: CHG-001 — Action exposure (legacy picker vs v2 capability)
| Field | Detail |
|---|---|
| Change Type | Modified component (action availability) |
| Surface | AI Agent config → Add action |
| Before | No Qontak-native actions |
| After | Legacy static picker lists 3: Create deal, Create Ticket, Update Ticket (bot-automation-actions-constants.ts + mirrored ai-agent-actions-constants.ts). The v2 capability agent loads tools from the DB (ai_agent_tools, BOT-4230/4293), not the static list. |
| Element | Before | After |
|---|---|---|
Legacy ACTION_LIST (Mekari Qontak group) | empty | Create deal, Create Ticket, Update Ticket |
| Backend executors on master | none | 4 CRM (mekari_qontak_crm) + 3 chat (mekari_qontak_chat) |
| Gap | — | Update Deal + Assign/Resolve/Tag have executors but are not in the legacy picker (see Section 16) |
Figma: N/A — backend actions; legacy picker exposes no net-new UI.
8. API & Webhook Behavior
| # | Behavior | Entity Affected | Triggered By | Expected Behavior | Failure Behavior |
|---|---|---|---|---|---|
| 1 | Create deal | Qontak CRM deal | Agent function-calls qontak_crm_deal_create | POST /api/v3.1/deals with body (pipeline/stage/name/owner/tags), company-token auth; if customer_contact_association, lead IDs looked up by phone and added as crm_lead_ids first (execute.rb:251-265) | 401 → refresh token + retry; persistent failure surfaces to runtime |
| 2 | Create ticket | Qontak CRM ticket | qontak_crm_ticket_create | POST /api/v3.1/tickets with body, company-token auth | 401 → refresh + retry |
| 3 | Update ticket | Qontak CRM ticket | qontak_crm_ticket_update | PUT /api/v3.1/tickets/{{id}} with updated fields, company-token auth | id unresolved → no update, error to runtime |
| 4 | Update deal | Qontak CRM deal | qontak_crm_deal_update | PUT /api/v3.1/deals/{{id}} (name/stage_id/amount), company-token auth. Backend shipped; not in legacy picker | id unresolved → error |
| 5 | Assign agent | Conversation Room | qontak_chat_room_assign | assign_type: auto/division → AssignAgentRoundRobinWorker; agent → AssignAgentWorker (+optional closing_message) | channel integration not found → error, no worker |
| 6 | Resolve conversation | Conversation Room | qontak_chat_room_resolve | Enqueue ResolveRoomWorker (+optional closing message) | room / channel integration not found → error, no worker |
| 7 | Create tag | Conversation Room | qontak_chat_room_tag | Normalize tags (array / objects / CSV / AI-resolved) → enqueue BulkTagsRoomWorker | empty tags → error, no worker |
Evidence: mekari_qontak_crm/execute.rb:18-23,251-265; mekari_qontak_chat/execute.rb:74-175; crm_http_client.rb:68-160.
9. System Flow + User Stories + ACs
9.1 System Flow
Flow: Builder configures a Qontak action → agent invokes it at runtime · Type: User Journey + API/worker dispatch
- Builder opens AI Agent config and adds a Qontak-native action (legacy picker for the 3 exposed CRM actions; v2 capability agent registers tools from the DB).
- On agent train/sync, the action is available as a callable tool.
- At runtime, the agent evaluates the conversation and function-calls the action.
- The internal-service action-execute path routes via
NodeTypeRegistryGROUP→ the executor (mekari_qontak_crmormekari_qontak_chat). - CRM action → HTTP call to Qontak CRM with the company token. Chat action → enqueue the relevant Sidekiq worker on the Room.
- Failure branch — CRM 401 → refresh token + retry; chat room/channel not found or empty tags → error returned, no side effect.
📊 System Flow — Qontak Action execution
sequenceDiagram
participant B as Builder
participant Cfg as AI Agent Config
participant AG as AI Agent (function-calling)
participant EX as Action Executor (NodeTypeRegistry)
participant CRM as Qontak CRM API
participant W as Sidekiq Worker (Room)
B->>Cfg: Add Qontak action (legacy picker) / register tool (v2 DB)
Cfg->>AG: Action available as callable tool on train/sync
AG->>EX: function-call node_type (runtime)
alt CRM action (mekari_qontak_crm)
EX->>CRM: HTTP request + company token (Bearer)
CRM-->>EX: 200 OK
alt 401 Unauthorized
EX->>CRM: refresh company_token + retry
end
else Chat action (mekari_qontak_chat)
EX->>W: enqueue Assign/Resolve/Tag worker on Room
W-->>EX: queued (or error if room/channel not found / tags empty)
end
EX-->>AG: result (success / error)
9.2 User Stories
| User Story | Importance | Mockup / Technical Notes | Acceptance Criteria |
|---|---|---|---|
| [QACT-S01] — Create deal action As a builder, I want the agent to open a CRM deal in the right pipeline/stage, so that a qualified conversation becomes a tracked deal. | Must Have | Figma: N/A Data Fields: • crm_pipeline_id (number, required)• crm_stage_id (number, required)• name (string, required)• creator_id (number, optional)• customer_contact_association (bool)• tags (array, optional)Before-After Behavior: Before, no native deal-create; after, the agent calls qontak_crm_deal_create. | — Happy Path — • AC-1: Given a stored qontak_crm_company_token and CRM actions enabled, when the builder opens Add action, then "Create deals" appears under Mekari Qontak.• AC-2: Given it is configured and the agent calls it, then POST /api/v3.1/deals is sent with the body, Bearer-authenticated.• AC-3: Given name contains {{customer_name}}, when it runs, then the placeholder is interpolated from the conversation contact.• AC-4: Given customer_contact_association is true, when it runs, then lead IDs are looked up by phone and added as crm_lead_ids before creation.— Error / Unhappy Path — • ERR-1: Given the CRM API returns 401, when it runs, then the company token is refreshed and retried; persistent failure surfaces to the runtime. — Permission Model — • CAN: Admin / Bot Manager · CANNOT: roles without AI Agent edit rights · Unauthorized: action not listed. • Reversibility: the agent cannot undo a created deal — it is a Qontak CRM record, editable/deletable only in Qontak CRM, not via the agent. — UI States — • Loading: save in progress · Empty: n/a · Error: save/validation error · Success: action listed |
| [QACT-S02] — Create ticket action As a builder, I want the agent to open a CRM ticket in the right pipeline/stage, so that a support need is captured mid-conversation. | Must Have | Figma: N/A — backend action Data Fields: • crm_pipeline_id (number, required)• crm_stage_id (number, required)• name (string, required)• creator_id (number, optional)• customer_contact_association (bool)Before-After Behavior: Before, no native ticket-create; after, the agent calls qontak_crm_ticket_create. | — Happy Path — • AC-1: Given CRM ticket actions enabled, when the builder opens Add action, then "Create Ticket" appears under Mekari Qontak. • AC-2: Given it is configured, when the agent calls it, then POST /api/v3.1/tickets is sent with the body, company-token (Bearer) authenticated.• AC-3: Given name contains {{customer_name}}, when it runs, then the placeholder is interpolated from the conversation contact.— Error / Unhappy Path — • ERR-1: Given the CRM API returns 401, when it runs, then the company token is refreshed and retried; persistent failure surfaces to the runtime. — Permission Model — • CAN: Admin / Bot Manager · CANNOT: roles without AI Agent edit rights · Unauthorized: action not listed. • Reversibility: the agent cannot undo a created ticket — it is a Qontak CRM record, editable/deletable only in Qontak CRM, not via the agent. — UI States — • Loading: save in progress · Empty: n/a · Error: save/validation error · Success: action listed |
| [QACT-S03] — Update ticket action As a builder, I want the agent to modify an existing ticket, so that ticket state stays current as the conversation progresses. | Must Have | Figma: N/A — backend action Data Fields: • id (string, required) — target ticket• crm_pipeline_id (number)• crm_stage_id (number)• name (string)• creator_id (number, optional)Before-After Behavior: Before, no native ticket-update; after, the agent calls qontak_crm_ticket_update. | — Happy Path — • AC-1: Given CRM ticket actions enabled, when the builder opens Add action, then "Update Ticket" appears under Mekari Qontak. • AC-2: Given a target id and updated fields, when the agent calls it, then PUT /api/v3.1/tickets/{{id}} is sent, company-token authenticated.— Error / Unhappy Path — • ERR-1: Given id cannot be resolved at runtime, when the agent calls it, then no update is sent and the failure surfaces to the runtime.• ERR-2: Given the CRM API returns 401, when it runs, then the token is refreshed and retried. — Permission Model — • CAN: Admin / Bot Manager · CANNOT: roles without AI Agent edit rights · Unauthorized: action not listed. • Reversibility: an update is itself reversible by re-running with prior values; the ticket is a Qontak CRM record, also editable directly in Qontak CRM. — UI States — • Loading: save in progress · Empty: n/a · Error: save/validation error · Success: action listed |
| [QACT-S04] — Update deal action (backend shipped, not in legacy picker) As a builder, I want the agent to update a CRM deal — the backend executes it, but it is not yet selectable in the legacy picker. | Should Have | Figma: N/A — backend action Data Fields: • id (string, required) — target deal• name (string)• stage_id (string)• amount (integer, optional)• include_logs/limit/page (query, optional) · x_trace_id (header, optional)Before-After Behavior: Before, no native deal-update path; after, the qontak_crm_deal_update executor runs (backend), pending FE exposure. | — Happy Path — • AC-1: Given the qontak_crm_deal_update executor (PUT /api/v3.1/deals/{{id}}), when invoked via the runtime/internal API with updated fields, then the deal is updated, company-token authenticated (spec action_execute_qontak_crm_spec.rb:49-66).— Error / Unhappy Path — • ERR-1: Given id cannot be resolved, when invoked, then no update is sent and the failure surfaces.— Gap — • GAP-1: Given the legacy Add-action picker, then "Update Deal" is NOT listed (no FE ACTION_LIST entry); the v2 capability agent can register it from the DB.— Permission Model — • CAN: the AI Agent at runtime (where registered) · CANNOT: builders cannot add it via the legacy picker · Unauthorized: not exposed where not registered. — UI States — • N/A — backend/runtime action; no legacy-picker config UI |
| [QACT-S05] — Assign agent action (internal worker, not in legacy picker) As an AI Agent, I want to assign the conversation to an agent (auto round-robin, by division, or a specific agent), so that handoff happens without a human step. | Should Have | Figma: N/A — runtime action Data Fields: • assign_type (enum: auto/division/agent, required)• division_id (required when division)• agent_id (required when agent)• closing_message (string, optional)Before-After Behavior: Before, assignment needed a human/flow node; after, the agent calls qontak_chat_room_assign (internal workers). | — Happy Path — • AC-1: Given assign_type=auto, when the agent calls it, then AssignAgentRoundRobinWorker is enqueued for an online agent (execute_spec.rb:176+).• AC-2: Given assign_type=division + division_id, when called, then the round-robin worker is scoped to that division.• AC-3: Given assign_type=agent + agent_id, when called, then AssignAgentWorker is enqueued for that agent (optional closing_message passed).— Error / Unhappy Path — • ERR-1: Given the room's channel integration is not found, when called, then an error is returned and no worker is enqueued. • ERR-2: Given assign_type=division/agent with the id blank, when called, then it errors ("Division/Agent ID required").— Gap — • GAP-1: Not in the legacy picker; exposure via v2 capability/tool registration. — Permission Model — • CAN: the AI Agent at runtime · CANNOT: customers/human agents cannot trigger it · Unauthorized: not exposed where not registered. — UI States — • N/A — runtime action; no builder UI |
| [QACT-S06] — Resolve conversation action (internal worker, not in legacy picker) As an AI Agent, I want to resolve/close the conversation (optionally with a closing message), so that handled chats are closed cleanly. | Should Have | Figma: N/A — runtime action Data Fields: • closing_message (string, optional)Before-After Behavior: Before, resolving needed a human/flow node; after, the agent calls qontak_chat_room_resolve (ResolveRoomWorker). | — Happy Path — • AC-1: Given a resolve action, when the agent calls it, then ResolveRoomWorker is enqueued (with the closing message if provided) — execute_spec.rb:33-65.— Error / Unhappy Path — • ERR-1: Given the room or its channel integration is not found, when called, then an error is returned and no worker is enqueued ( execute_spec.rb:66-87).— Gap — • GAP-1: Not in the legacy picker; exposure via v2 capability/tool registration. — Permission Model — • CAN: the AI Agent at runtime · CANNOT: customers cannot trigger it · Unauthorized: not exposed where not registered. — UI States — • N/A — runtime action; no builder UI |
| [QACT-S07] — Create tag action (internal worker, not in legacy picker) As an AI Agent, I want to bulk-assign tags to the conversation room, so that conversations are categorized for reporting/routing. | Should Have | Figma: N/A — runtime action Data Fields: • tags (required) — array, array-of-objects (name), comma-separated string, or AI-resolvedBefore-After Behavior: Before, tagging needed a human/flow node; after, the agent calls qontak_chat_room_tag (BulkTagsRoomWorker). | — Happy Path — • AC-1: Given a tag action with tags as an array, when the agent calls it, then BulkTagsRoomWorker is enqueued with normalized tag names (execute_spec.rb:89-151).• AC-2: Given tags as objects/CSV/AI-resolved, when called, then they are normalized to tag names before enqueue. — Error / Unhappy Path — • ERR-1: Given tags are empty, when called, then an error is returned and no worker is enqueued ( execute_spec.rb:152-162).— Gap — • GAP-1: Not in the legacy picker; exposure via v2 capability/tool registration. — Permission Model — • CAN: the AI Agent at runtime · CANNOT: customers cannot trigger it · Unauthorized: not exposed where not registered. — UI States — • N/A — runtime action; no builder UI |
| [QACT-S01-NEG] — Out-of-scope actions (Guard Rail — from Non-Goals) As a builder, I should not find non-Qontak-native actions in this initiative. | Guard Rail | — | — Negative Scenarios — • NEG-1: Given the Add-action surface, when the builder looks for Talenta/Jurnal/Desty actions, then they are not offered here — they belong to Mekari Action (HMAC). • NEG-2: Given the Add-action surface, when the builder looks for Google/Calendly/Midtrans, then they are not offered here — they belong to Native Integration (OAuth). • NEG-3: Given the Add-action surface, when the builder looks for Send Attachment, then it is not documented here — it is tracked by its own PRD. |
Dependencies: S02–S07 depend on the shared action framework (Section 14). GAP-1 rows track the FE-exposure gap (Section 16).
🧪 Test Coverage Matrix — [QACT-S01]
| Dimension | Coverage | Notes |
|---|---|---|
| Boundary values | ⚠️ TBD | ⚠️ QA: missing required pipeline/stage; very long deal name |
| State transitions | ✅ defined | AC-1 listing → AC-2 execution |
| Data validation | ⚠️ partial | AC-3 interpolation covered; ⚠️ QA: invalid pipeline/stage IDs |
| Concurrency | ⚠️ TBD | ⚠️ QA: agent fires create-deal twice in rapid turns |
| Network/timeout | ✅ defined | ERR-1 401 refresh + retry |
🧪 Test Coverage Matrix — [QACT-S02] / [QACT-S03]
| Dimension | Coverage | Notes |
|---|---|---|
| Boundary values | ⚠️ TBD | ⚠️ QA: update-ticket with unresolved id (S03 ERR-1 covers the no-op) |
| State transitions | ✅ defined | listing → execution |
| Data validation | ⚠️ TBD | ⚠️ QA: invalid stage transitions |
| Concurrency | ⚠️ TBD | ⚠️ QA: two updates to same ticket |
| Network/timeout | ✅ defined | company-token 401 refresh + retry |
10. Rollout
| Field | Detail |
|---|---|
| Feature flag | ai_agent_action (org) / rollout_ai_agent_action (system preference) + crm_deal/crm_ticket subscriptions; ai_agent_action_api for the generic api action (Section 6) |
| Rollout | Historical (as-built): CRM actions rolled out behind the flags above; the 3 exposed actions are live in the legacy picker. Backend executors for all 7 are on master. |
| Backward compat | Yes — additive; existing flows and the api action are unaffected |
| Migration | None |
11. Observability
As-built note: Qontak-Action-specific events are not yet implemented — execution currently flows through the generic node path (
ExecutionLogger.log_execution(node_type:)). The table below is the recommended instrumentation to close that gap; treat it as the spec, not as shipped. Planned: the PM will add these later via the Mixpanel event tracker (follow the repo'smixpaneltracking pattern for event naming + property conventions).
Key Events (recommended):
| Event Name | Trigger | Properties |
|---|---|---|
qontak_action_configured | Builder saves a Qontak action | node_type, agent_id, organization_id, timestamp |
qontak_action_invoked | Agent function-calls an action (pre-result) | node_type, agent_id, conversation_id, timestamp |
qontak_action_executed | Executor completes successfully | node_type, agent_id, conversation_id, organization_id, timestamp |
qontak_action_failed | Executor errors (CRM 401-after-retry, id-unresolved, room/channel-not-found, empty-tags) | node_type, reason, agent_id, conversation_id, timestamp |
qontak_action_token_refreshed | CRM company token refreshed on 401 | organization_id, outcome, timestamp |
Dashboard owner: BOT — Chatbot & AI Squad.
Alerts:
qontak_action_failedrate > 10% of invocations over a rolling 1h window → notify BOT on-call (Slack)qontak_action_token_refreshedwithoutcome=failed> 5 in 15 min for one org → notify BOT + CRM on-call
11.1 Post-Launch Monitoring Cadence
| Field | Detail |
|---|---|
| Review cadence | Weekly for the first 4 weeks after instrumentation lands, then monthly |
| Owner | BOT — Chatbot & AI Squad (PM: Dimas) |
| Review scope | Action execution success rate, failure-reason mix, per-node_type volume |
| Trigger thresholds | qontak_action_failed rate > 10% w/w → investigate within 48h; token-refresh failures trending up → page CRM |
| Rollback consideration | If a node_type's failure rate is sustained > 20% for 24h, disable that action's node_registries.enabled flag while root-causing |
12. Success Metrics
As-built note: these actions shipped without a committed metric set; the targets below are proposed (to confirm in review) and depend on the Section 11 instrumentation landing first.
Adoption & Usage (proposed):
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| ⭐ Action adoption | % of active AI Agents with ≥1 Qontak action configured | N/A — not instrumented | ≥ 30% of active AI Agents within 90 days of instrumentation |
| Action execution volume | Count of successful qontak_action_executed / week | 0 (no events today) | Sustained week-over-week growth through the first 8 weeks |
Quality (proposed):
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| Action success rate | qontak_action_executed / (executed + failed) × 100 | N/A | ≥ 97% within 60 days of instrumentation |
| CRM token-refresh success | successful refreshes / total 401-triggered refreshes × 100 | N/A | ≥ 99% |
13. Launch Plan & Stage Gates
As-built note: the actions already shipped via feature flags, so most stages are retrospective. The one forward item is closing the FE-exposure gap (§16) — captured as the "Full exposure" stage gate below.
Retrospective (as-built):
| Stage | Audience | Status | Notes |
|---|---|---|---|
| Internal / flag rollout | Accounts with ai_agent_action / rollout_ai_agent_action ON | Done | CRM actions behind per-action suite components (Sales/Service) |
| Legacy picker GA | Builders with the flags + the relevant suite component | Done (3 actions) | Create deal (CP-QONTAKCRM-2025-0005), Create/Update Ticket (CP-QONTAKCRM-2025-0002) |
Forward (planned, not scheduled):
| Stage | Audience | Success Gate to Advance | Owner |
|---|---|---|---|
| Full exposure | All AI Agent builders | The 4 shipped-but-unlisted actions (Update Deal + assign / resolve / tag) are reachable to builders — via legacy ACTION_LIST entries and/or confirmed v2 capability-tool registration, verified against node_registries / ai_agent_tools | BOT — Chatbot & AI Squad |
14. Dependencies
| Dependency | Owning Team | Deliverable Needed | Blocking? |
|---|---|---|---|
AI Agent action/tool framework (AiAgentAction, AiAgentTool, node_type_registry.rb) | BOT | Stable executor routing + tool registration (BOT-4230/4293) | YES |
| Qontak CRM API + company-token connection | BOT / CRM (Core) | qontak_crm_company_token connection + CRM endpoints | YES (CRM actions) |
Conversation workers (AssignAgentRoundRobinWorker, AssignAgentWorker, ResolveRoomWorker, BulkTagsRoomWorker) | BOT | Internal workers operating on the Room | YES (chat actions) |
| AI Service function-calling | AI Service team | Invoke the registered tools at runtime | YES |
node_registries catalog + ai_agent_tools registration (runtime DB) | BOT | Enabled rows so actions are reachable in the v2 agent | YES (for v2 exposure) |
15. Key Decisions + Alternatives Rejected
8a — Decisions Made
| Date | Decision | Rationale |
|---|---|---|
| 2026-06-17 | Split Qontak-native actions into their own initiative, separate from Mekari Action | Different target (Qontak's own features) + auth (company token vs HMAC) |
| 2026-02 | CRM actions authenticate via the company token (qontak_crm_company_token) | First-party Qontak APIs; no cross-product approval needed |
| 2026-03–05 | Chat actions (assign/resolve/tag) execute via internal Sidekiq workers on the Room | They operate on the org's own conversation data; no external API/token |
| 2026-02 | Model Qontak Action as a catalog of independent actions, not a linear phase rollout | Actions ship on their own timelines on the shared framework |
8b — Alternatives Rejected
| Alternative | Why Rejected | Date |
|---|---|---|
| Authenticate CRM actions with HMAC (like Mekari Action) | Qontak's own APIs accept the company token; HMAC is for cross-Mekari-product calls | 2026-02 |
| Route chat actions through an external API with a token | They act on internal org rooms; internal workers are simpler and have no auth surface | 2026-03 |
| Document assign/resolve/tag as "prototype-only" (the v1.0 error) | They have shipped, spec-covered executors on master — corrected after a thorough re-check | 2026-06-17 |
16. Open Questions
| # | Type | Question | Owner | Deadline |
|---|---|---|---|---|
| 1 | Open Question | FE-exposure gap: Update Deal + Assign/Resolve/Tag have shipped executors but are not in the legacy action picker. Should we add legacy ACTION_LIST entries, or rely on v2 capability-tool registration? Decide deliberately. | Dimas (PM) + BOT | Backlog grooming (no hard date) |
| 2 | Open Question | v2 reachability (verification-blocked): Whether these 4 actions are reachable in the v2 agent today depends on enabled node_registries rows + registered ai_agent_tools — runtime DB data, not in the repo. Confirm via a DB/staging query (SELECT node_type, enabled FROM node_registries WHERE node_type IN (...)) or a Mixpanel usage check. | BOT | 2026-06-24 |
| 3 | Open Question | Should per-action observability events (Section 11) be added to measure adoption/reliability? Planned via the Mixpanel event tracker. | Dimas (PM) | Backlog / later (Mixpanel) |
| 4 | Assumption | The v2 capability agent surfaces any executor registered as an ai_agent_tool with a non-null tool_id (generate.rb:52-56) — assumed sufficient to expose the 4 unlisted actions without FE changes. Validate alongside #2. | BOT | 2026-06-24 |
PRD CHANGELOG
| Version | Date | By | Section | Type | Summary |
|---|---|---|---|---|---|
| 1.0 | 2026-06-17 | Claude | All | CREATED (REVERSE) | As-built documentation of released Qontak-native CRM actions. Contained an error: labelled Assign/Resolve/Tag as prototype-only. |
| 1.1 | 2026-06-17 | Claude | §2,§3,§5,§6,§8 | CORRECTED | Corrected after a thorough re-check: Assign/Resolve/Tag + Update Deal have shipped, spec-covered backend executors on master; reframed the gap as legacy-FE-picker exposure; documented the CRM-token vs internal-worker auth split. |
| 2.0 | 2026-06-17 | Claude | All | REFORMATTED | Reformatted from the reverse/as-built document into the standard Qontak PHASE template (HEADER, ToC, CONDITIONAL BLOCK, S3–S16, CHANGELOG) to match the sibling Phase PRD. Stories converted to the 4-column Section-9 table with strict Gherkin ACs + Guard Rail negatives + Test Coverage Matrices; gap-flagged Observability / Success Metrics / Launch Plan (not applicable to an as-built record — flagged, not fabricated). No factual changes vs v1.1. |
| 2.1 | 2026-06-17 | Claude | S9, S11, S12 | MODIFIED | Applied scorer Group-A fills: added a System Flow mermaid diagram (S9.1); deepened stories S02–S07 with Permission Model + 4 UI States + Data Fields and converted the Guard Rail to strict Given/When/Then; spec'd Observability as recommended instrumentation (5 events + alerts + post-launch cadence); set proposed Success Metrics targets. Remaining flags (Constraints perf/data, Observability-not-implemented, Metrics-proposed, Launch-retrospective) left for the section-by-section runthrough. |
| 2.3 | 2026-06-17 | Claude | S9 | MODIFIED | Applied score improvement [I1]: added an explicit Reversibility line to the Permission Model of the three Must stories (QACT-S01/S02/S03) — created deals/tickets cannot be undone via the agent (CRM records, editable/deletable in Qontak CRM); updates are re-runnable. Clears the Layer-2.5 Q2 (rollback) gap → all Must stories RFC-Ready. |
| 2.2 | 2026-06-17 | Claude | S6, S11, S12, S13, S16 | MODIFIED | Section-by-section runthrough with PM: S6 — set feature-flag defaults (ai_agent_action/rollout_ai_agent_action default OFF) and added per-action billing components (Deal → CP-QONTAKCRM-2025-0005 Sales Suite; Ticket → CP-QONTAKCRM-2025-0002 Service Suite; chat actions inherit base AI Agent component), perf/data marked N/A — cited to feature_detail.rb:6-13. S11 — kept as recommendation; noted Mixpanel tracker as the planned instrumentation path (PM to add later). S12 — proposed targets confirmed. S13 — added a forward "Full exposure" stage gate for the FE-exposure work alongside the retrospective record. S16 — set owners + deadlines (v2-reachability DB check 2026-06-24; FE-exposure + Mixpanel events = backlog). |