Skip to main content

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 chatbot BE + chatbot-fe FE, 2026-06-17), reformatted into the standard Qontak PHASE structure. Every load-bearing claim cites file:line or a commit/Jira key. This is a record of shipped behavior + its gaps, not a plan for new work.

HEADER BLOCK

FieldValue
PMDimas Fauzi Hidayat
PRD Version2.3
StatusSHIPPED (as-built record)
PRD TypePHASE (reverse / as-built)
EpicBOT-3476 · BOT-3496 · BOT-3662
SquadBOT — Chatbot & AI Squad
RFC LinkN/A — as-built documentation
Figma MasterN/A — backend actions; legacy picker has no net-new UI
AnchorYes — Qontak Action — ANCHOR
Labelsepic:qontak-chatbot | module:ai-agent | feature:qontak-action
Last Updated2026-06-17

Status values: DRAFTREADYBUILDSHIPPED. 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:

SectionGapImpact
11. ObservabilityEvents are recommended, not yet implementedAdoption/reliability not measurable until instrumentation lands
12. Success MetricsTargets are proposed (confirmed in review), pending Mixpanel instrumentationNo committed baseline until events land

Table of Contents

2. CONDITIONAL BLOCK: PHASE CONTEXT

FieldDetail
Anchor PRDQontak Action — ANCHOR
Phase NumberNot a sequential phase — an as-built catalog of Qontak-native actions under the Qontak Action initiative
Phase GoalDocument 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 phasesCRM 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 phaseAs-built record of 4 CRM actions (company token) + 3 chat actions (internal workers), reconstructed from the repos
Deferred to nextClosing the FE-exposure gap (Update Deal + the 3 chat actions); Send Attachment (own PRD); the prototype-only labels with no executor
Cross-phase depsShared 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

PersonaRoleGoalPainWorkaround
Primary — CS Ops Lead / Bot ManagerCustomer-side bot owner who configures the AI Agent in Qontak ChatbotLet the agent perform Qontak operations (open a deal/ticket, tag, assign, resolve) mid-conversation without a human or a hand-built flowOnly 3 of the shipped actions appear in the legacy action picker; Update Deal + the chat actions aren't selectable there despite working backendsBuild 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 conversationCall 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

  1. Not introducing new actions — this PRD documents already-shipped behavior; it adds no capability.
  2. Not changing the auth model — company token (CRM) and internal workers (chat) are recorded as-is.
  3. Send Attachment action — tracked by its own PRD (phase-4-send-attachment-action.md); excluded here.
  4. Mekari-product and third-party actions — owned by the Mekari Action (HMAC) and Native Integration (OAuth) initiatives, not this one.
  5. 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.
  6. Prototype-only labels with no executor — none remain in scope; all 7 documented actions have backends.

6. Constraints

FieldValue
PlatformConfiguration — Qontak web app. Runtime — the AI Agent function-calls actions during a conversation on any supported channel.
Auth — CRM actionsQontak 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 actionsInternal — 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 flagai_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 limitsN/A — backend actions; inherit Qontak CRM API + platform limits. No Qontak-Action-specific latency/size/quota constraints.
Registry gatingnode_registries.enabled per action (DB). Source: chatbot/app/models/node_registry.rb:29.
Read/writeConfigure — 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)

FieldDetail
Change TypeModified component (action availability)
SurfaceAI Agent config → Add action
BeforeNo Qontak-native actions
AfterLegacy 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.
ElementBeforeAfter
Legacy ACTION_LIST (Mekari Qontak group)emptyCreate deal, Create Ticket, Update Ticket
Backend executors on masternone4 CRM (mekari_qontak_crm) + 3 chat (mekari_qontak_chat)
GapUpdate 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

#BehaviorEntity AffectedTriggered ByExpected BehaviorFailure Behavior
1Create dealQontak CRM dealAgent function-calls qontak_crm_deal_createPOST /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
2Create ticketQontak CRM ticketqontak_crm_ticket_createPOST /api/v3.1/tickets with body, company-token auth401 → refresh + retry
3Update ticketQontak CRM ticketqontak_crm_ticket_updatePUT /api/v3.1/tickets/{{id}} with updated fields, company-token authid unresolved → no update, error to runtime
4Update dealQontak CRM dealqontak_crm_deal_updatePUT /api/v3.1/deals/{{id}} (name/stage_id/amount), company-token auth. Backend shipped; not in legacy pickerid unresolved → error
5Assign agentConversation Roomqontak_chat_room_assignassign_type: auto/divisionAssignAgentRoundRobinWorker; agentAssignAgentWorker (+optional closing_message)channel integration not found → error, no worker
6Resolve conversationConversation Roomqontak_chat_room_resolveEnqueue ResolveRoomWorker (+optional closing message)room / channel integration not found → error, no worker
7Create tagConversation Roomqontak_chat_room_tagNormalize tags (array / objects / CSV / AI-resolved) → enqueue BulkTagsRoomWorkerempty 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

  1. 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).
  2. On agent train/sync, the action is available as a callable tool.
  3. At runtime, the agent evaluates the conversation and function-calls the action.
  4. The internal-service action-execute path routes via NodeTypeRegistry GROUP → the executor (mekari_qontak_crm or mekari_qontak_chat).
  5. CRM action → HTTP call to Qontak CRM with the company token. Chat action → enqueue the relevant Sidekiq worker on the Room.
  6. 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 StoryImportanceMockup / Technical NotesAcceptance 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 HaveFigma: 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 HaveFigma: 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 HaveFigma: 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 HaveFigma: 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 HaveFigma: 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 HaveFigma: 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 HaveFigma: N/A — runtime action

Data Fields:
tags (required) — array, array-of-objects (name), comma-separated string, or AI-resolved

Before-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]

DimensionCoverageNotes
Boundary values⚠️ TBD⚠️ QA: missing required pipeline/stage; very long deal name
State transitions✅ definedAC-1 listing → AC-2 execution
Data validation⚠️ partialAC-3 interpolation covered; ⚠️ QA: invalid pipeline/stage IDs
Concurrency⚠️ TBD⚠️ QA: agent fires create-deal twice in rapid turns
Network/timeout✅ definedERR-1 401 refresh + retry

🧪 Test Coverage Matrix — [QACT-S02] / [QACT-S03]

DimensionCoverageNotes
Boundary values⚠️ TBD⚠️ QA: update-ticket with unresolved id (S03 ERR-1 covers the no-op)
State transitions✅ definedlisting → execution
Data validation⚠️ TBD⚠️ QA: invalid stage transitions
Concurrency⚠️ TBD⚠️ QA: two updates to same ticket
Network/timeout✅ definedcompany-token 401 refresh + retry

10. Rollout

FieldDetail
Feature flagai_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)
RolloutHistorical (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 compatYes — additive; existing flows and the api action are unaffected
MigrationNone

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's mixpanel tracking pattern for event naming + property conventions).

Key Events (recommended):

Event NameTriggerProperties
qontak_action_configuredBuilder saves a Qontak actionnode_type, agent_id, organization_id, timestamp
qontak_action_invokedAgent function-calls an action (pre-result)node_type, agent_id, conversation_id, timestamp
qontak_action_executedExecutor completes successfullynode_type, agent_id, conversation_id, organization_id, timestamp
qontak_action_failedExecutor errors (CRM 401-after-retry, id-unresolved, room/channel-not-found, empty-tags)node_type, reason, agent_id, conversation_id, timestamp
qontak_action_token_refreshedCRM company token refreshed on 401organization_id, outcome, timestamp

Dashboard owner: BOT — Chatbot & AI Squad.

Alerts:

  • qontak_action_failed rate > 10% of invocations over a rolling 1h window → notify BOT on-call (Slack)
  • qontak_action_token_refreshed with outcome=failed > 5 in 15 min for one org → notify BOT + CRM on-call

11.1 Post-Launch Monitoring Cadence

FieldDetail
Review cadenceWeekly for the first 4 weeks after instrumentation lands, then monthly
OwnerBOT — Chatbot & AI Squad (PM: Dimas)
Review scopeAction execution success rate, failure-reason mix, per-node_type volume
Trigger thresholdsqontak_action_failed rate > 10% w/w → investigate within 48h; token-refresh failures trending up → page CRM
Rollback considerationIf 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):

MetricDefinitionBaselineTarget
⭐ Action adoption% of active AI Agents with ≥1 Qontak action configuredN/A — not instrumented≥ 30% of active AI Agents within 90 days of instrumentation
Action execution volumeCount of successful qontak_action_executed / week0 (no events today)Sustained week-over-week growth through the first 8 weeks

Quality (proposed):

MetricDefinitionBaselineTarget
Action success rateqontak_action_executed / (executed + failed) × 100N/A≥ 97% within 60 days of instrumentation
CRM token-refresh successsuccessful refreshes / total 401-triggered refreshes × 100N/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):

StageAudienceStatusNotes
Internal / flag rolloutAccounts with ai_agent_action / rollout_ai_agent_action ONDoneCRM actions behind per-action suite components (Sales/Service)
Legacy picker GABuilders with the flags + the relevant suite componentDone (3 actions)Create deal (CP-QONTAKCRM-2025-0005), Create/Update Ticket (CP-QONTAKCRM-2025-0002)

Forward (planned, not scheduled):

StageAudienceSuccess Gate to AdvanceOwner
Full exposureAll AI Agent buildersThe 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_toolsBOT — Chatbot & AI Squad

14. Dependencies

DependencyOwning TeamDeliverable NeededBlocking?
AI Agent action/tool framework (AiAgentAction, AiAgentTool, node_type_registry.rb)BOTStable executor routing + tool registration (BOT-4230/4293)YES
Qontak CRM API + company-token connectionBOT / CRM (Core)qontak_crm_company_token connection + CRM endpointsYES (CRM actions)
Conversation workers (AssignAgentRoundRobinWorker, AssignAgentWorker, ResolveRoomWorker, BulkTagsRoomWorker)BOTInternal workers operating on the RoomYES (chat actions)
AI Service function-callingAI Service teamInvoke the registered tools at runtimeYES
node_registries catalog + ai_agent_tools registration (runtime DB)BOTEnabled rows so actions are reachable in the v2 agentYES (for v2 exposure)

15. Key Decisions + Alternatives Rejected

8a — Decisions Made

DateDecisionRationale
2026-06-17Split Qontak-native actions into their own initiative, separate from Mekari ActionDifferent target (Qontak's own features) + auth (company token vs HMAC)
2026-02CRM actions authenticate via the company token (qontak_crm_company_token)First-party Qontak APIs; no cross-product approval needed
2026-03–05Chat actions (assign/resolve/tag) execute via internal Sidekiq workers on the RoomThey operate on the org's own conversation data; no external API/token
2026-02Model Qontak Action as a catalog of independent actions, not a linear phase rolloutActions ship on their own timelines on the shared framework

8b — Alternatives Rejected

AlternativeWhy RejectedDate
Authenticate CRM actions with HMAC (like Mekari Action)Qontak's own APIs accept the company token; HMAC is for cross-Mekari-product calls2026-02
Route chat actions through an external API with a tokenThey act on internal org rooms; internal workers are simpler and have no auth surface2026-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-check2026-06-17

16. Open Questions

#TypeQuestionOwnerDeadline
1Open QuestionFE-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) + BOTBacklog grooming (no hard date)
2Open Questionv2 reachability (verification-blocked): Whether these 4 actions are reachable in the v2 agent today depends on enabled node_registries rows + registered ai_agent_toolsruntime 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.BOT2026-06-24
3Open QuestionShould per-action observability events (Section 11) be added to measure adoption/reliability? Planned via the Mixpanel event tracker.Dimas (PM)Backlog / later (Mixpanel)
4AssumptionThe 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.BOT2026-06-24

PRD CHANGELOG

VersionDateBySectionTypeSummary
1.02026-06-17ClaudeAllCREATED (REVERSE)As-built documentation of released Qontak-native CRM actions. Contained an error: labelled Assign/Resolve/Tag as prototype-only.
1.12026-06-17Claude§2,§3,§5,§6,§8CORRECTEDCorrected 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.02026-06-17ClaudeAllREFORMATTEDReformatted 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.12026-06-17ClaudeS9, S11, S12MODIFIEDApplied 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.32026-06-17ClaudeS9MODIFIEDApplied 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.22026-06-17ClaudeS6, S11, S12, S13, S16MODIFIEDSection-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).