Qontak | AI Agent | Meta Business Agent Integration — Phase 2: MBA Management & Config Sync
HEADER BLOCK
| Field | Value |
|---|---|
| PM | Dimas Fauzi Hidayat |
| PRD Version | 1.8 |
| Status | DRAFT (gated: MBA GA + pricing in Indonesia — see Anchor Open Question 1) |
| PRD Type | PHASE (Phase 2 of 3) |
| Epic | TBD — add once Epic is created |
| Squad | Chatbot (BOT) |
| RFC Link | N/A — RFC to follow after PRD is READY |
| Figma Master | Pending — low-fi wireframes embedded in §6 (channel section, Resources sync column); Figma TBD |
| Anchor | Yes — Qontak | AI Agent | Meta Business Agent Integration — ANCHOR |
| Labels | epic:qontak-chatbot | module:ai-agent | feature:meta-business-agent |
| Last Updated | 2026-07-19 |
Table of Contents
- HEADER BLOCK
- CONDITIONAL BLOCK: PHASE CONTEXT
- One-liner + Problem
- Target Users + Persona Context
- Non-Goals
- Scope Changes
- Constraints
- New Features
- API & Webhook Behavior
- System Flow + User Stories
- Rollout
- Observability
- Success Metrics
- Launch Plan & Stage Gates
- Dependencies
- Key Decisions + Alternatives Rejected
- Open Questions
- PRD CHANGELOG
CONDITIONAL BLOCK: PHASE CONTEXT
| Field | Value |
|---|---|
| Anchor PRD | Qontak | AI Agent | Meta Business Agent Integration — ANCHOR |
| Phase | Phase 2 of 3 |
| Phase Goal (verbatim from Anchor Phase Index) | Let org admins onboard, configure, and operate MBA from Qontak — eligibility → onboarding → allowlist → settings on the channel page, with admin-selected knowledge/persona synced from the existing AI agent on publish. |
| Prior phases | Phase 1 shipped the MBA-aware foundation: standby/messaging_handovers consumption, standby persistence, room control state, Thread Control release (hand-back), inbox control UI, and the mba_aware_inbox flag. |
| Deferred to later phases | Phase 3: connector gateway (MBA executing Qontak-hosted actions), Actions "Meta connector" expose column, MBA agent test/eval integration. |
| Cross-phase dependencies | This phase writes MBA lifecycle status onto the WABA account model and requires Phase 1's control-state + suppression behavior to be live (an onboarded agent immediately produces standby traffic). The Phase 1 conflict guard (no Qontak automation on MBA rooms) becomes user-facing here as the one-AI-per-number enable guard. |
Evidence note (research grounding): sources: [] — carried from Phase 1: no direct user
research exists yet on MBA adoption intent. Phase 1 beta design-partner interviews are the
planned evidence input for this phase's GA decision; if they invalidate demand, this phase
stays gated regardless of MBA GA.
2. One-liner + Problem
One-liner: Let org admins onboard, configure, and turn on Meta Business Agent from the Qontak channel page, with the knowledge and persona they select synced from their existing AI agent on publish.
Problem: After Phase 1, Qontak can observe and control MBA conversations — but customers still have to onboard and configure MBA in WhatsApp Manager and Meta's raw APIs, re-entering knowledge and persona that already live in their Qontak AI agent. That duplication makes WhatsApp Manager, not Qontak, the natural home of the agent: config drifts between two systems, and Qontak loses the management seat that Track 1 of the strategic response exists to defend. Org admins get no eligibility visibility, no controlled-rollout allowlist, and no guard against enabling two AI responders on one number.
3. Target Users + Persona Context
| Persona | Role | Goal | Pain | Workaround |
|---|---|---|---|---|
| Primary — Org Admin | Admin who owns channel integrations and the AI agent config in Qontak | Enable Meta's AI on a number in minutes, reusing the knowledge/persona already built in Qontak, with a safe test-then-go-live path | MBA onboarding lives in WhatsApp Manager + raw Graph APIs; knowledge/persona must be re-entered by hand and drifts from the Qontak agent | Configure in WhatsApp Manager and maintain two divergent agent configs — or skip MBA |
| Secondary — CS Supervisor | Supervisor accountable for AI answer quality | Trust that what MBA knows matches what the team curated in Qontak, and see when sync last happened | No visibility into what was pushed to Meta or when; a stale KB answers customers wrongly | None — manual spot checks on live conversations |
(See Constraints for plan availability and feature flag scope.)
4. Non-Goals
- No connector gateway / action execution — MBA calling Qontak-hosted actions, and the Actions "Meta connector" column, are Phase 3.
- No MBA test/eval integration — Phase 3.
- No second agent builder — persona, tone, language, guidance, and handoff are configured only in the existing AI agent (Profile/Capabilities/Routing). The only authoring additions are the inline per-field Meta overrides on those same Profile fields (S08) — a parallel builder or duplicated agent config entity stays out of scope.
- No two-way sync — Qontak → Meta only; config changed directly in WhatsApp Manager is not imported back (Qontak is the source of truth; drift is surfaced, not merged).
- No automatic migration from an active Qontak bot flow / AI agent to MBA — the conflict guard blocks enable and the admin resolves it manually this phase.
- No sync for non-mappable source types —
APIsources have no Meta knowledge equivalent and are marked "Not syncable" (their transactional role is Phase 3's connector tools). (Corrected via ground-prd 2026-07-19: the V2 agent'sAiKnowledgeSourcetypes are file / url / text / api / ocr —ai_knowledge_source.rb:15; a "Conversation history" type exists only in the separate ChatbotGpt/Ask-Airene subsystem and is not on this surface.) - No mobile app changes — web only.
- No packaging/billing implementation — pricing model is an Anchor open question; this phase ships behind a flag either way, and the upsell surface (if paid) is a follow-up ADJUSTMENT.
Scope Changes
Engineering surfaces this PRD touches (controlled vocab). Kept in sync with the scope_changes frontmatter above.
- Backend —
hub-core: new MBA management module besidewa_embedded_signupwrapping Meta's MBA Platform endpoints (eligibility, onboarding +agent_idstorage, allowlist, settings incl. audience/follow-up — settings PUT is full-replace, always send the complete object) on a newapi.facebook.comclient (X-API-Version: 2.0.0; not thewa_cloudGraph client); MBA lifecycle status field onwaba_accounts(mirroring themm_lite_api_statuspattern); one-AI-per-number enable guard.chatbot:SyncToMetaMbarepository as a second sync target besideSyncToAiServicein the V2 agent save/update flow (create_ai_agent.rb:61/update_ai_agent.rb:61— the only trigger points whereSyncToAiServicefires; ground-prd 2026-07-19: the V1 publish/AiAgentHistory/TrainAiAgentFromHistoryflow is a disjoint legacy subsystem and is NOT the trigger) (source-type mapping: Text content → FAQs, External URL → Websites, File upload → Files, OCR file → Files (Meta accepts PNG/JPG/JPEG natively), API → Not syncable, Business info → business_info; Profile/capabilities → Skills collection with per-skill limits title ≤64 / description ≤1,024 / body ≤20,000 chars; Routing exits →handoff.enabled(derivation rule at RFC — routing entries are{type, then, exit: {reason}}free text,sync_to_ai_service.rb:538-546, no message field);handoff.messageleft unset so Meta's default applies (PM decision 2026-07-19: the handover reads seamlessly within the conversation — no custom message, no new authored field)); per-item Meta-id mapping with create/update/delete reconciliation on publish (FAQs/websites/files/skills all carry per-item ids at Meta — never blind-replace); per-source Meta-sync scope flag (mba_sync_enabled, default ON — only enabled sources are pushed; a source toggled OFF is removed at Meta on the next publish); per-field Profile Meta-override precedence (override ?? shared value); per-source sync-status tracking. The MBA sync path is AI-Services-free — raw content is read from Qontak-owned stores (OSS file objects, source records, URLs) and pushed straight to Meta;SyncToAiServiceand its vector-store layer serve the Qontak agent only (§5). - Frontend — channel WhatsApp Account details page (hub-chat
features/integrations/whatsapp/views/WhatsAppDetailPage.vue— the v2 page): new "Meta Business Agent" section (status, eligibility, onboarding, linked AI agent, audience row (Everyone / Test numbers only, folding the allowlist Manage action in), follow-up row (toggle + Meta's fixed interval enum + message), visibility toggle + confirmation modal, conflict banner) following the WhatsApp call/catalog/commerce section anatomy (WhatsAppCatalog.vuebadge +MpToggle+ confirm-MpModalpattern).chatbot-feBot automation → Training sources → AI resources (modules/ai-knowledge— the Bot-automation-linked one of the repo's three sources implementations; real columns: Source name · Source type · Status · Update date): deployment banner, "Meta sync" column (per-source scope toggle + status — status chip reuses theMpBadge tableStatuspattern; a per-row toggle cell has no existing precedent, net-new), sync-status filter, "Business info" source type (structured form, "Meta only" badge); AI agent builder (V2,modules/bot-automationAiAgentEditor.vue) → Profile: inline per-field "Meta override" expanders (default: inherit; anchored on the existing per-field change-highlight namespaceprofile.goals / toneOfVoice / language / guidance.{id}). - Design — Figma for the channel section and the Resources column states (low-fi wireframes exist).
5. Constraints
| Field | Value |
|---|---|
| Platform | Web only (channel settings + Bot automation). |
| Performance | Eligibility check result rendered ≤ 5s (p95). Publish → Meta sync enqueued ≤ 30s; per-source sync status visible ≤ 10 min (p95) after publish (website crawling is Meta-side and excluded from the SLA — shown as "Crawling…"). |
| Data limits | Per Meta docs v2.0.0: files ≤100 MB (PDF/DOC/DOCX/PNG/JPG/JPEG, +CSV/XLSX "when enabled" — OQ-7); skills title ≤64 / description ≤1,024 / body ≤20,000 chars (save-time validation, S08 ERR-1); FAQ/website count limits undocumented (OQ-4). The sync must surface Meta's rejection per source, never truncate silently. |
| Plan scope | TBD — packaging is Anchor Open Question 3 (paid add-on via the commerce upsell pattern vs included). Build is packaging-agnostic behind the flag. |
| Feature flag | mba_management | default: OFF. Enabled per organization. Requires mba_aware_inbox active (Phase 1) — enabling management without awareness is blocked. |
| Eligibility | Meta-gated (EU exclusion, vertical exclusions, Cloud API, good standing) — Qontak surfaces Meta's verdict + reason, never overrides it. |
| One AI per number | Hard guard: MBA cannot be enabled on a number with an active Qontak bot flow / AI agent deployment, and vice versa. |
| Side-by-side coexistence | Explicitly supported at the org level: MBA on number A and the Qontak AI agent on number B, both driven by the same linked agent config. Divergence is scoped, never forked — per-source/per-action scope toggles (S06 / Phase 3), per-field Profile Meta overrides (S08), MBA-only operational settings on the channel section (S07). One authoring surface, no duplicated agent entity. |
| No Mekari AI Services dependency | The entire MBA path is Qontak-owned (chatbot squad), end to end. Today's Qontak-agent flow sends knowledge to Mekari AI Services for ingestion/vector stores (SyncToAiService → oss.get_url → AI Service); the MBA path bypasses that completely: SyncToMetaMba reads raw content from Qontak's own stores — file bytes from the Alicloud OSS objects already referenced by AiKnowledgeSource.data, FAQ/Text content from the records, URLs as-is — and pushes straight to Meta, which does its own ingestion/crawling/embedding. No AI Service call, no vector store, no embedding anywhere in the MBA path. SyncToAiService continues unchanged for the Qontak agent only. |
| Data lifecycle | Sync-status records follow the knowledge source's lifecycle (deleted with the source). Toggling a source's Meta sync OFF removes it from Meta's knowledge base on the next publish while the source keeps serving the Qontak agent. Disconnecting MBA retains the local config/status history for audit; nothing is deleted at Meta beyond turning the agent off. |
6. New Features
Surface 1: existing WhatsApp channel Account details page — one new section (no new page).
Account details (existing)
└── Meta Business Agent section (NEW — same anatomy as WhatsApp call/catalog/commerce)
├── Status row — MpBadge Active/Inactive
├── Eligibility row — badge Eligible/Not eligible + checked timestamp + reason on failure
├── Agent onboarding row — badge Not started/Prepared + "Set up with Meta" action
├── AI agent row — linked agent name → Bot automation (source of config)
├── Audience row — Everyone / Test numbers only (ai_audience) + allowlist count + Manage
│ (folds the test-allowlist management in; switch = confirmation modal)
├── Follow-up row — MpToggle + interval select (Meta's fixed enum) + message (modal)
├── Agent visibility row — MpToggle + state text + confirmation modal (catalog-visibility pattern)
└── Conflict banner — shown when a Qontak bot flow / AI agent is active on this number
Surface 2: existing Bot automation → Training sources → "AI resources" page (modules/ai-knowledge) — additive elements only.
Resources (existing)
├── Deployment banner (NEW) — "deployed to MBA on {number} · sources sync on publish · last publish {time} by {actor}"
├── "Meta sync" column (NEW) — per-source scope toggle (default ON; OFF = Qontak-only)
│ + status: Synced / Queued / Crawling… / Failed(+Retry) / Off / Not syncable
├── "Business info" source type (NEW) — one per agent, structured form modal
│ (description · contact · hours · payment · delivery · purchase · returns),
│ "Meta only" badge — the Qontak agent does not consume it this phase
└── "Meta sync" filter (NEW)
Surface 3: existing AI agent builder → Profile tab — inline additions only.
Profile (existing: Goals & behavior · Tone of voice · Language · Response guidance)
└── Per-field "Customize for Meta agent" expander (NEW, default: inherit)
├── collapsed: "Inherited — same as Qontak agent"
└── expanded: override editor + "Reset to shared" + Meta limit counter (64/1,024/20,000)
UI states: eligibility loading (skeleton row) · not-eligible (danger badge + Meta's reason + Learn more) · sync failed (badge + retry per source) · sync off (toggle OFF → status "Off"; skipped on publish, removed at Meta if previously synced, still serves the Qontak agent) · empty (org with no MBA onboarding sees only the section's default state — zero change elsewhere).
Wireframe 1 — channel Account details, new "Meta Business Agent" section (existing vs. new):
The new section (dashed-blue block) reuses the exact row anatomy of the page's existing WhatsApp call / catalog / commerce sections — status badge, toggle + state text, confirmation modal, and a Meta-icon "Connect" text link — so it reads as one more capability on the number, not a new surface. Persona/tone/language/handoff are deliberately absent here; they stay in the AI agent (the "AI agent" row links out to it). Note: the v1 frame predates the Audience and Follow-up rows (S07, added 2026-07-18) — they follow the same row anatomy; the Figma (Dependency 5) must include them.
Wireframe 2 — Bot automation → Resources, new "Meta sync" column (existing vs. new):
The existing Resources table (tabs, summary strip, source rows) is unchanged; the three dashed-blue additions are the deployment banner, the per-source "Meta sync" column (scope toggle + status), and the sync-status filter. The toggle is the admin's per-source scope choice: ON (default) syncs the source to Meta on publish; OFF keeps it Qontak-only — skipped on publish and removed at Meta if previously synced (status "Off"). This is the knowledge-side mirror of Phase 3's per-action "Meta connector" expose toggle, so knowledge and actions share one MBA-vs-Qontak scoping model. The source-type → Meta mapping (Text content → FAQs, External URL → Websites, File upload / OCR file → Files, API → Not syncable) is annotated on the frame.
Figma TBD (Dependency 5).
7. API & Webhook Behavior
Plain-language contract; Graph specifics belong to the RFC. All calls use the existing
wa_cloudGraph client pattern and per-channel LOCKBOX tokens.
| # | Behavior | Entity Affected | Triggered By | Expected Behavior | Failure Behavior |
|---|---|---|---|---|---|
| 1 | Check eligibility | WABA account MBA status | Admin opens the MBA section / clicks re-check | Call Meta's eligibility endpoint for the number; store verdict + checked-at; render badge. Docs v2.0.0 return only is_eligible (no reason field) — on Not eligible, render Meta's published criteria (country/vertical/Cloud API/standing) as guidance, not a fabricated reason (OQ-6) | API error → badge shows "Couldn't check" + retry; verdict never guessed |
| 2 | Prepare agent (onboarding) | WABA account MBA status | Admin clicks "Set up with Meta" | Call Meta onboarding; on success status = Prepared (agent exists but OFF); prompt admin to link an AI agent if none linked | Meta rejection → status unchanged, reason shown, mba_onboarding_failed logged |
| 3 | Manage test allowlist | MBA allowlist | Admin adds/removes test numbers | Call Meta allowlist endpoint; list mirrored locally for display | Per-number failure shown inline; partial success allowed |
| 4 | Sync config on publish | Meta knowledge base + skills + settings | Admin saves/publishes the linked V2 AI agent (the existing SyncToAiService trigger — create_ai_agent.rb:61 / update_ai_agent.rb:61) | SyncToMetaMba maps and pushes every source the admin left enabled for Meta sync (per-source toggle, default ON): Text content→FAQs, External URL→Websites, File upload→Files, OCR file→Files, API→Not syncable, Business info→business_info, Profile/capabilities→Skills collection (per-field Meta overrides take precedence over shared values; per-skill limits validated at save), Routing exits→handoff.enabled (rule at RFC); handoff.message left to Meta's default (PM decision 2026-07-19); per-item Meta-id reconciliation — create/update/delete diffed against stored Meta ids, never blind-replace; per-source status recorded; OFF sources are skipped (status Off) and removed at Meta if previously synced; deletes propagate (source removed in Qontak → removed at Meta) | Per-source failure → status Failed + Retry (does NOT roll back other sources); publish itself never blocked by Meta errors (policy per Open Question 1); repeated failure alerts (§10) |
| 5 | Turn agent ON | MBA settings, WABA MBA status | Admin toggles visibility ON + confirms modal | Guard: block if a Qontak bot flow / AI agent is active on the number (conflict banner names it); else call Meta settings enable (full-replace PUT with the complete settings object); status = Active; Phase 1 inbox behavior takes over from the first conversation. Note (docs): re-enabling resumes new threads only — in-flight threads stay unanswered by MBA | Guard block → modal explains + links the conflicting automation; Meta error → toggle reverts + toast |
| 6 | Turn agent OFF | MBA settings, WABA MBA status | Admin toggles OFF + confirms | Call Meta settings disable; status = Inactive; existing MBA-controlled rooms keep Phase 1 behavior until control returns | Meta error → toggle stays ON + toast + retry |
| 7 | Surface config drift | Sync status | Admin edited MBA config directly in WhatsApp Manager (detected on next sync) | Next publish overwrites Meta with Qontak state (one-way source of truth); the section shows "last synced" so staleness is visible | — |
| 8 | Update operational settings | MBA settings | Admin changes Audience or Follow-up on the channel section | Settings PUT with the complete settings object (full-replace semantics — enabled + handoff + followup + ai_audience together); local mirror updated on success | Meta error → control reverts + toast + retry; partial writes impossible by construction (single full-replace call) |
Meta API surface & build map — this phase's slice (docs v2.0.0, fetched 2026-07-18):
Pipeline independence (§5): every row below runs chatbot/hub-core → Meta directly. Mekari AI Services appears nowhere in the MBA path — Meta ingests, crawls, and embeds on its own side. The AI-Services flow (
SyncToAiService, vector stores) keeps serving only the Qontak agent.
| Meta surface | Endpoints & key facts (v2.0.0) | Qontak builds | Reuses | Where |
|---|---|---|---|---|
| Agent Eligibility | GET /{phone_number_id}/agent_eligibility → is_eligible boolean only — no reason field | Eligibility check + verdict/checked-at stored on waba_accounts; criteria-as-guidance rendering on Not eligible | mm_lite_api_status lifecycle pattern | S01, OQ-6 |
| Agent Onboarding | POST /{phone_number_id}/agent_onboarding?channel=whatsapp → agent_id; async data-prep; channel enum is omnichannel (email, instagram, line, messenger, sms, tiktok, webchat, whatsapp) — MBA is not WhatsApp-bound long-term (strategic watch, ties to click-to-webchat) | Onboarding call + agent_id persistence | same WABA lifecycle pattern | S02 |
| Agent Settings | GET/PUT /{phone_number_id}/agent_config/settings?agent_id= — enabled; handoff{enabled, message}; followup{enabled, interval ∈ {0,300,900,1800,3600,7200,28800,86400}s, message}; ai_audience ∈ {EVERYONE, ALLOWLISTED_ONLY}; PUT = create-or-fully-replace; re-enable resumes new threads only | Settings wrapper that always sends the complete object; enable/disable with conflict guard; Audience + Follow-up rows | channel-section row anatomy (call/catalog/commerce) | S05, S07, §7 #5/#8 |
| Agent Allowlist | GET/POST /{phone_number_id}/agent_config/allowlist, DELETE …/{entry_id}; consumer_phone_number E.164; per-entry ids; size cap undocumented (OQ-4) | Allowlist add/remove/list + local mirror | — | S04 (Manage folds into the S07 Audience row) |
| Agent Skills | Full CRUD /{phone_number_id}/agent_config/skills[/{skill_id}] — a collection, not one blob; per skill title ≤64 (lowercase/numbers/hyphens), description ≤1,024 (trigger context), skill body ≤20,000 chars | Each Qontak capability → one Meta skill; save-time limit validation; per-field Meta-override precedence (override ?? shared) | capability/skill_pack translation (SyncToAiService pattern) | S03, S08, OQ-3 (resolved) |
| Business Info | GET/PUT/DELETE /{phone_number_id}/agent_config/business_info — structured singleton: business_description, payment_method, return_policy, purchase_info, delivery_and_shipping, contact_info{email, address, hours_of_operation} | New "Business info" source type (structured form, "Meta only" badge); PUT on publish, DELETE resets to defaults | Resources "Add source" flow, org profile as prefill | S09, OQ-8 |
| FAQs | Full CRUD /{phone_number_id}/agent_config/faq[/{faq_id}] — question/answer/metadata, per-item ids | Text content → FAQ mapping with id-mapped create/update/delete reconciliation (never blind-replace) | AiKnowledgeSource FAQ/TEXT types | S03, S06 |
| Websites | Full CRUD /{phone_number_id}/agent_config/websites[/{website_id}] — url; crawl_status ∈ {pending, in_progress, completed, failed}, pages_crawled, last_crawled_at | External URL mapping; crawl status surfaced as "Crawling…" in the Meta sync column | Resources status column | S03, S06 |
| Files | POST/GET/DELETE knowledge files — multipart (file_name + binary); ≤100 MB; PDF/DOC/DOCX/PNG/JPG/JPEG (+CSV/XLSX "when enabled" — OQ-7) | Stream the raw OSS object (already referenced by AiKnowledgeSource.data) as multipart binary to Meta — Meta takes bytes, not URLs; per-file format/size gate with a "Not syncable (format)" state for files Meta doesn't accept; OCR-file sources ride the same path (PNG/JPG accepted natively by Meta) | file-type AiKnowledgeSource + Alicloud OSS objects (Qontak-owned — no AI Services in the path) | S03, S06, OQ-4 (narrowed) |
8. System Flow + User Stories
System Flow
- Admin opens the WhatsApp channel Account details page; the new MBA section runs an eligibility check and renders the verdict.
- Failure branch: not eligible → danger badge + Meta's reason; flow ends (re-check available).
- Admin clicks "Set up with Meta" → onboarding prepares the agent (exists, still OFF).
- Admin links the AI agent (or confirms the suggested one) — the section shows it as the config source.
- Admin reviews Resources and toggles Meta sync OFF on any source that must stay Qontak-only (default: every syncable source syncs).
- Admin saves/publishes the V2 AI agent in Bot automation (the existing
SyncToAiServicetrigger) →SyncToMetaMbapushes the enabled knowledge/persona/handoff; AI resources shows per-source sync status (OFF sources show "Off"). - Failure branch: a source fails to sync → Failed badge + Retry on that row; publish is not rolled back.
- Admin adds test numbers to the allowlist and verifies answers on a test device.
- Admin toggles the agent ON → conflict guard checks for an active Qontak automation on the number.
- Failure branch: conflict → enable blocked, banner names the conflicting bot flow / AI agent deployment.
- On success MBA answers new conversations; Phase 1 takes over runtime (standby persistence, control state, take-over/hand-back).
System-flow diagram (User Journey — mirrors the numbered steps above, all three failure branches included):
sequenceDiagram
autonumber
actor Adm as Org Admin
participant Q as Qontak (channel page + Bot automation)
participant M as Meta MBA Platform API
Adm->>Q: Open MBA section on the channel
Q->>M: Check eligibility
alt Not eligible
M-->>Q: Verdict + reason
Q-->>Adm: "Not eligible" badge + reason (flow ends — re-check available)
else Eligible
M-->>Q: Eligible
Adm->>Q: Set up with Meta
Q->>M: Onboarding (prepare agent)
M-->>Q: Prepared (agent OFF)
Adm->>Q: Link AI agent (config source)
Adm->>Q: (Optional) Toggle Meta sync OFF on Qontak-only sources
Adm->>Q: Save/publish V2 AI agent (existing SyncToAiService trigger)
Q->>M: SyncToMetaMba — enabled knowledge / Skills / handoff
alt A source fails to sync
M-->>Q: Reject source
Q-->>Adm: Failed + Retry on that row (publish NOT rolled back)
else All syncable sources pushed
M-->>Q: Synced (per-source status)
end
Adm->>Q: Add test numbers (allowlist) + verify answers
Adm->>Q: Toggle agent ON
alt Qontak bot flow / AI agent active on this number
Q-->>Adm: Enable blocked — conflict banner names the automation
else No conflict
Q->>M: Settings enable
M-->>Q: Active
Note over Q,M: MBA answers new conversations — Phase 1 runtime takes over
end
end
User Stories
| User Story | Importance | Mockup | Technical Notes | Acceptance Criteria |
|---|---|---|---|---|
| [MBA2-S01] — Check eligibility on the channel page As an org admin, I want to see whether my number can use MBA and why not if it can't, so that I don't chase an agent Meta will refuse. | Must Have | §6 channel wireframe — Figma TBD | Data Fields: • mba_eligibility (enum + reason, timestamp) — source: Meta eligibility API, stored on WABA accountBefore-After Behavior: Before: no MBA surface exists in Qontak; eligibility only discoverable in WhatsApp Manager. After: the channel section shows Eligible/Not eligible with Meta's reason and checked-at timestamp. | — Happy Path — • AC-1: Given an eligible number, when the admin opens the section, then the Eligible badge renders with the checked timestamp within 5s (p95). • AC-2: Given an ineligible number, when checked, then the Not eligible badge renders with a re-check action and Meta's published eligibility criteria as guidance (docs v2.0.0 return only is_eligible, no reason field — no reason is ever fabricated; OQ-6).— Error / Unhappy Path — • ERR-1: Given the eligibility call fails, when the section loads, then "Couldn't check" renders with retry and no cached verdict is invented. — Permission Model — • CAN: org admin • CANNOT: agents/supervisors — section visible read-only, actions hidden |
| [MBA2-S02] — Prepare the agent from Qontak As an org admin, I want to onboard MBA on my number from the channel page, so that setup doesn't require WhatsApp Manager or raw APIs. | Must Have | §6 channel wireframe — Figma TBD | Data Fields: • mba_status (enum: none | prepared | active | inactive) on WABA account — mirrors mm_lite_api_status patternBefore-After Behavior: Before: onboarding only via WhatsApp Manager. After: "Set up with Meta" calls onboarding; status row shows Prepared; agent stays OFF until S06. | — Happy Path — • AC-1: Given an eligible number, when the admin clicks "Set up with Meta" and Meta accepts, then status = Prepared and the section prompts to link an AI agent. • AC-2: Given onboarding succeeded, when the page reloads, then the state persists (idempotent — no duplicate onboarding call). — Error / Unhappy Path — • ERR-1: Given Meta rejects onboarding, when the call returns, then status is unchanged, the rejection reason shows, and mba_onboarding_failed is logged. |
| [MBA2-S03] — Sync agent config to Meta on publish As an org admin, I want my AI agent's knowledge and persona pushed to MBA when I publish, so that one curated config drives both agents with zero re-entry. | Must Have | §6 Resources wireframe | Data Fields: • per-source meta_sync_status (enum: synced | queued | crawling | failed | not_syncable, + synced_at, actor)• mapping: Text content→FAQs, External URL→Websites, File upload / OCR file→Files, API→Not syncable, Profile→Skills, Routing exits→handoff.enabled (message = Meta default) Before-After Behavior: Before: the V2 save/update fires SyncToAiService only. After: it also fires SyncToMetaMba for MBA-linked agents; deletes propagate; Resources shows per-source status. | — Happy Path — • AC-1: Given a prepared MBA linked to an agent, when the admin publishes, then all Meta-sync-enabled syncable sources are pushed with correct type mapping and marked Synced with actor + timestamp within 10 min (p95, excluding Meta-side crawling). • AC-2: Given a source is removed in Qontak, when the next publish runs, then it is removed from Meta's knowledge base. • AC-3: Given an API source, when publish runs, then it is skipped and marked "Not syncable" (never sent — its transactional role is Phase 3's connector tools).— Error / Unhappy Path — • ERR-1: Given Meta rejects one source, when sync completes, then that source shows Failed + Retry, other sources are unaffected, and mba_sync_source_failed is logged with Meta's error.• ERR-2: Given the retry also fails 3 times, when the admin views Resources, then the banner shows a persistent sync-issue warning (§10 alert fires). |
| [MBA2-S04] — Manage the test allowlist As an org admin, I want to restrict the agent to test numbers before go-live, so that I can verify answers safely. | Should Have | §6 channel wireframe — Figma TBD | Data Fields: • allowlisted consumer numbers (mirrored locally from Meta) Before-After Behavior: Before: allowlist only via raw API. After: Manage action on the section row adds/removes numbers. | — Happy Path — • AC-1: Given a prepared agent, when the admin adds a test number, then Meta's allowlist is updated and the row count reflects it. — Error / Unhappy Path — • ERR-1: Given one of several numbers fails, when the call returns, then failures are shown per number and successes persist. |
| [MBA2-S05] — Turn the agent on/off with a conflict guard As an org admin, I want a guarded on/off switch for MBA, so that I never run two AI responders on one number. | Must Have | §6 channel wireframe — Figma TBD | Data Fields: • mba_status transitions prepared↔active↔inactive• conflict check against active bot flow / AI agent deployments on the channel Before-After Behavior: Before: enable only in WhatsApp Manager, no guard — double-responder possible. After: toggle + confirmation modal (catalog-visibility pattern); enable blocked while a Qontak automation is active on the number. | — Happy Path — • AC-1: Given no conflicting automation, when the admin toggles ON and confirms, then Meta settings enable is called and status = Active. • AC-2: Given an active agent, when toggled OFF and confirmed, then Meta disable is called and status = Inactive. — Error / Unhappy Path — • ERR-1: Given an active Qontak bot flow or AI agent on the number, when the admin toggles ON, then enable is blocked and the conflict banner names the conflicting deployment with a link to it. • ERR-2: Given the Meta call fails, when the toggle action returns, then the toggle reverts, a toast shows, and the action is retryable. — Permission Model — • CAN: org admin • CANNOT: supervisor/agent — toggle not rendered |
| [MBA2-S06] — Choose which knowledge sources sync to MBA As an org admin, I want a per-source Meta sync toggle on the Resources page, so that I control exactly what Meta's agent knows and can keep internal or sensitive knowledge Qontak-only. | Must Have | §6 Resources wireframe — Figma TBD | Data Fields: • mba_sync_enabled (bool, default true) per knowledge source• meta_sync_status gains the off valueBefore-After Behavior: Before: publish syncs every syncable source — all-or-nothing, no way to hold a source back from Meta. After: each source row carries a Meta sync toggle; OFF sources are skipped on publish, removed at Meta if previously synced, and keep serving the Qontak agent. Knowledge-side mirror of Phase 3's per-action "Meta connector" expose toggle. | — Happy Path — • AC-1: Given a source is toggled OFF, when the admin publishes, then it is skipped (status "Off"), absent from Meta's knowledge base, and still used by the Qontak AI agent ( SyncToAiService unchanged).• AC-2: Given a previously synced source is toggled OFF, when the next publish runs, then it is removed from Meta's knowledge base and its status shows "Off". • AC-3: Given an OFF source is toggled back ON, when the next publish runs, then it syncs and shows Synced. — Error / Unhappy Path — • ERR-1: Given the Meta-side removal call fails, when sync completes, then the source shows Failed + Retry (not "Off") and mba_sync_source_failed is logged with Meta's error.— Permission Model — • CAN: org admin • CANNOT: supervisor/agent — toggle rendered read-only |
| [MBA2-S07] — Control who MBA talks to and how it follows up As an org admin, I want audience and follow-up settings for MBA on the channel page, so that I can go live safely (test numbers first) and let the agent re-engage customers on my terms. | Must Have | §6 channel wireframe — Figma TBD | Data Fields: • ai_audience (EVERYONE | ALLOWLISTED_ONLY) via settings PUT• followup {enabled, interval ∈ Meta's fixed enum {0, 300, 900, 1800, 3600, 7200, 28800, 86400}s, message}• settings PUT is full-replace — the complete object is always sent (§7 #8) Before-After Behavior: Before: audience/follow-up reachable only via Meta's raw settings API; S04 manages allowlist numbers but nothing switches the agent between test-only and everyone. After: an Audience row (Everyone / Test numbers only + Manage, folding S04's action in) and a Follow-up row (toggle + interval + message) on the MBA channel section. | — Happy Path — • AC-1: Given a prepared agent, when the admin sets Audience to "Test numbers only", then settings PUT sends ai_audience=ALLOWLISTED_ONLY and only allowlisted numbers get MBA replies.• AC-2: Given Audience is switched to Everyone and the confirmation modal is accepted, then settings PUT updates and the row reflects the live state. • AC-3: Given follow-up is enabled with an interval and message, when saved, then the complete settings object is PUT (other fields preserved by construction). — Error / Unhappy Path — • ERR-1: Given the settings call fails, when the save returns, then the control reverts, a toast shows, and the action is retryable. — Permission Model — • CAN: org admin • CANNOT: supervisor/agent — rows read-only |
| [MBA2-S08] — Override Profile fields for MBA where they must differ As an org admin, I want per-field Meta overrides on my agent's Profile, so that MBA can speak differently where it must while everything else stays shared with my Qontak agent. | Should Have | §6 Surface 3 — Figma TBD (Dependency 5) | Data Fields: • per-field meta_override (nullable) for Goals & behavior, Tone of voice, Language, Response guidance• sync precedence: override ?? shared value (S03/§7 #4); overrides affect SyncToMetaMba only, never SyncToAiService• Meta skill limits enforced at save (title ≤64 slug | description ≤1,024 | body ≤20,000) | — Happy Path — • AC-1: Given a Tone override is set, when the admin publishes, then Meta receives the override while the Qontak agent keeps the shared tone (AI-service payload unchanged). • AC-2: Given an override is cleared ("Reset to shared"), when the next publish runs, then Meta receives the shared value again. — Error / Unhappy Path — • ERR-1: Given an override exceeds a Meta skill limit, when the admin saves, then a validation error names the limit and blocks the save — nothing is truncated silently. — Permission Model — • CAN: org admin • CANNOT: supervisor/agent — expanders read-only |
| [MBA2-S09] — Author Business info for MBA As an org admin, I want a structured Business info source, so that MBA answers store questions (hours, payment, shipping, returns) from curated facts instead of loose text. | Should Have | §6 Resources wireframe — Figma TBD | Data Fields: • singleton per linked agent: {business_description, payment_method, return_policy, purchase_info, delivery_and_shipping, contact_info{email, address, hours_of_operation}} • synced via business_info PUT on publish; removal → business_info DELETE (Meta resets to defaults)• "Meta only" badge — the Qontak agent does not consume it this phase (OQ-8) | — Happy Path — • AC-1: Given Business info is filled, when the admin publishes, then business_info PUT pushes it and the row shows Synced.• AC-2: Given the Business info source is removed, when the next publish runs, then business_info DELETE resets Meta to defaults.— Error / Unhappy Path — • ERR-1: Given Meta rejects the payload, when sync completes, then the row shows Failed + Retry and sibling sources are unaffected (same policy as S03). — Permission Model — • CAN: org admin • CANNOT: supervisor/agent — form read-only |
| [MBA2-S01-NEG] — No config authored outside the AI agent (Guard Rail — from Non-Goal 3) As an org admin, when I look for persona/knowledge fields in the MBA section, then none exist — only a link to the AI agent. | Guard Rail | — | — | NEG-1: Given the MBA section is fully set up, when the admin inspects it, then it contains zero persona/knowledge/handoff-authoring input fields — operational delivery settings (visibility, audience, follow-up — S05/S07) are the section's scope, and the AI agent row links to Bot automation as the only authoring surface. |
| [MBA2-S02-NEG] — One-way sync only (Guard Rail — from Non-Goal 4) As the sync engine, when config differs at Meta, then Qontak state overwrites it on publish and nothing is imported back. | Guard Rail | — | — | NEG-1: Given MBA config was edited directly in WhatsApp Manager, when the next publish syncs, then Meta reflects Qontak's state and no Meta-side values are written into Qontak. |
Dependencies: MBA2-S02 depends on S01 (eligible); S03 depends on S02 (prepared + linked agent); S05 depends on S02; S04 depends on S02; S06 depends on S02 and scopes what S03 pushes (the toggle decides the sync set); S07 depends on S02 (folds S04's Manage action into the Audience row); S08 and S09 feed S03's sync payload.
9. Rollout
| Stage | Audience | Duration | Exit condition |
|---|---|---|---|
| Stage 0 — Internal QA | Qontak test org, allowlisted test WABA | 2 weeks | Gate 1 |
| Stage 1 — Closed beta | The Phase 1 design-partner orgs (already MBA-piloted), flag ON per org | 4 weeks | Gate 2 |
| Stage 2 — GA | Per packaging decision (Anchor OQ-3): flag default ON, or gated behind the add-on | — | Gate 3 |
No migration window: orgs that onboarded MBA directly in WhatsApp Manager before this phase see the section reflect Meta's actual state on first load (status/eligibility read live) and can adopt sync by linking an agent — pre-existing Meta-side config is overwritten on their first publish, which the link flow warns about explicitly.
10. Observability
| Event | Trigger | Key properties |
|---|---|---|
mba_eligibility_checked | S7 #1 | org_id, waba_id, verdict, reason |
mba_onboarding_{succeeded,failed} | S7 #2 | org_id, waba_id, meta_error_code |
mba_sync_run | S7 #4 per publish | org_id, agent_id, sources_total, synced, failed, skipped, excluded_off |
mba_source_sync_toggled | Admin flips a source's Meta sync toggle | org_id, source_id, source_type, enabled, actor |
mba_sync_source_failed | S7 #4 per failure | org_id, source_id, source_type, meta_error_code |
mba_agent_{enabled,disabled} | S7 #5/#6 | org_id, waba_id, actor |
mba_settings_updated | S7 #8 | org_id, waba_id, ai_audience, followup_enabled, followup_interval, actor |
mba_profile_override_{set,cleared} | S08 save | org_id, agent_id, field, actor |
mba_enable_blocked_conflict | S7 #5 guard | org_id, conflicting_deployment_type |
Dashboard owner: Chatbot squad.
Alert thresholds: sync-run failure rate > 10% over 24h → investigate; any org with 3+ consecutive failed syncs on the same source → notify support; onboarding failure rate > 20% over 7d → check API-version drift with Meta.
Post-Launch Monitoring Cadence
Weekly for the first 4 weeks post-GA (Dimas F + Chatbot EM). Immediate investigation triggers: sync success < 99% weekly, or any confirmed case of MBA answering from stale knowledge > 24h after a publish.
11. Success Metrics
Adoption & Usage:
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| ⭐ MBA-through-Qontak attach rate | % of MBA-enabled customer numbers onboarded via Qontak (vs directly in WhatsApp Manager) | ~0% (no surface exists) | ≥70% within 2 quarters of GA (the Anchor's north star — this phase is its engine) |
| Onboarding completion | % of started setups (S02) reaching Active (S05) | N/A | ≥60% within 30 days of start |
Quality & Accuracy:
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| Sync success rate | Enabled syncable sources marked Synced ÷ enabled syncable sources per publish (OFF sources excluded) | N/A | ≥99% |
| Config freshness | p95 publish → all sources Synced (excl. crawling) | N/A | ≤ 10 min |
Efficiency & Impact:
| Metric | Definition | Baseline | Target |
|---|---|---|---|
| Setup time | Median eligibility-check → Active | N/A (WhatsApp Manager path unmeasured) | ≤ 1 day (incl. test-allowlist verification) |
12. Launch Plan & Stage Gates
| Gate | Stage | Criteria (measurable) |
|---|---|---|
| Gate 1 — QA exit | Stage 0 → 1 | Full onboarding funnel green on the test WABA (eligibility → prepared → synced → allowlisted → active); type-mapping verified per source type; per-source scope toggle verified (an OFF source is absent from Meta's KB and still answers via the Qontak agent); conflict guard blocks enable with an active bot flow AND with an active AI agent; disable/re-enable round-trip clean |
| Gate 2 — Beta exit | Stage 1 → 2 | ≥2 partner orgs live through the full funnel; sync success ≥99% over 2 weeks; zero double-responder incidents; partner interviews confirm the no-re-entry value proposition |
| Gate 3 — GA | Post-GA | Packaging decision implemented (OQ from Anchor resolved); §10 cadence green 4 weeks |
13. Dependencies
| # | Dependency | Owner | Blocking? | Notes |
|---|---|---|---|---|
| 1 | Phase 1 shipped (control state, suppression, inbox behavior) | Chatbot squad | YES | An enabled agent immediately produces standby traffic; Phase 1 is the runtime. |
| 2 | MBA GA + pricing in Indonesia (Anchor OQ-1) + BSP/BISU terms (Anchor OQ-2) | Dimas F via Meta partner manager | YES | The phase's build gate — PRD stays DRAFT until resolved. |
| 3 | Meta MBA management API access on production WABAs (beyond pilot allowlist) | Meta | YES | Confirms endpoints/payloads are stable at GA. |
| 4 | Packaging decision (paid add-on vs included) | Dimas F + Pricing | NO (blocks Gate 3, not build) | Build is packaging-agnostic behind mba_management. |
| 5 | Figma for channel section + Resources states | Design (Wulan) | NO | Low-fi wireframes exist. |
14. Key Decisions + Alternatives Rejected
14a — Decisions Made
| Date | Decision | Rationale |
|---|---|---|
| 2026-07-08 | Sync fires on the existing V2 save/update (publish) flow, as a second target beside SyncToAiService | The V2 flow already fires SyncToAiService (create_ai_agent.rb:61 / update_ai_agent.rb:61) and is the trained user behavior; no new "sync" concept for admins to learn. (Corrected 2026-07-19: AiAgentHistory versioning belongs to the disjoint V1 subsystem — not this trigger.) |
| 2026-07-08 | One-way sync, Qontak → Meta; Meta-side edits overwritten on next publish | Two-way merge is unownable; Qontak is the source of truth (Track 3 principle); staleness surfaced via "last synced" |
| 2026-07-08 | MBA lifecycle status stored on waba_accounts, cloned from the mm_lite_api_status pattern | Verified pattern in code; multi-WABA-ready by construction |
| 2026-07-08 | Conflict guard is a hard block at enable time (not a warning) | Double-responder is a customer-facing failure; Phase 1's runtime suppression is the safety net, not the primary control |
| 2026-07-08 | Per-source sync failure does not block publish or roll back sibling sources | Publish serves the Qontak AI path too; a Meta outage must not freeze the customer's own agent (final policy: OQ-1) |
| 2026-07-18 | Per-source Meta-sync scope toggle on Resources, default ON | The admin — not the sync engine — decides which knowledge is for MBA vs Qontak-only; default ON preserves the zero-re-entry value prop; mirrors Phase 3's per-action "Meta connector" expose toggle so knowledge and actions share one scoping model |
| 2026-07-18 | Side-by-side coexistence via one authoring surface + scoped divergence (S06/S07/S08/S09 + Phase 3 expose toggle) | MBA and the Qontak agent run side-by-side at org level off the same linked config; divergence is per-item/per-field opt-out or override, never a forked agent entity — no drift, no double authoring, no new pages |
| 2026-07-18 | MBA-only operational settings (audience, follow-up) live on the channel MBA section; handoff message uses Meta's default — no custom message (revised 2026-07-19: routing exits carry only a free-text reason; the sole message candidate, profile.idle_rule.assign.message, is an inactivity rule with different semantics — PM decision: Meta default keeps the handover seamless within the conversation) | They are per-number delivery settings with no Qontak-agent equivalent — the channel section is the per-number home (call/catalog/commerce precedent); no custom handoff message keeps the S01-NEG guard rail intact (zero authoring on the channel page) |
| 2026-07-19 | Zero Mekari AI Services dependency in the MBA path — SyncToMetaMba reads raw content from Qontak's own stores (OSS file objects, source records, URLs) and pushes straight to Meta | PM requirement: MBA is owned by Qontak end-to-end, no DSAI/AI-Services involvement (standing cross-team-dependency rule). Technically free: Meta does its own ingestion, so AI Services would add a dependency with zero function; code-verified that raw files already live in Qontak's OSS (AiKnowledgeSource.data → oss.get_url) |
14b — Alternatives Rejected
| Alternative | Why Rejected | Date |
|---|---|---|
| Dedicated "Sync to Meta" button instead of publish-triggered sync | Second mental model + guaranteed drift between the two agents' configs | 2026-07-08 |
| Import existing Meta-side MBA config into Qontak on first link | Two-way merge complexity for a transient migration case; explicit overwrite warning is honest and simpler | 2026-07-08 |
| Auto-disable the Qontak bot flow when MBA is enabled | Silent deactivation of a live automation is a support incident by design; the admin resolves the conflict knowingly | 2026-07-08 |
| Build the paid-upsell surface in this phase | Packaging undecided (Anchor OQ-3); the commerce upsell pattern can be added as a small ADJUSTMENT once priced | 2026-07-08 |
| All-or-nothing sync (every syncable source always pushed, no per-source choice) | Forces admins with internal-only knowledge (SOPs, escalation notes, pricing floors) to either leak it to Meta's agent or strip it from their Qontak agent | 2026-07-18 |
| Per-source toggle defaulting OFF (opt-in, like the Phase 3 action toggle) | Kills the zero-re-entry promise for the common case; knowledge informs while actions act — read exposure defaults open, execute exposure defaults closed | 2026-07-18 |
| Separate MBA agent builder / duplicated agent config entity for divergent config | Two sources of truth guarantee drift and double authoring — the exact failure the one-way sync exists to prevent; scoped per-field overrides deliver divergence at a fraction of the surface | 2026-07-18 |
| Putting audience/follow-up settings in the AI agent builder | They are per-number operational delivery settings (which number, which recipients, re-engagement cadence), not agent authoring — the channel section is the established per-number home | 2026-07-18 |
Routing MBA knowledge through Mekari AI Services ingestion (reuse the existing SyncToAiService/vector-store pipeline) | Meta ingests/crawls/embeds on its own side, so AI Services would add a cross-team dependency with zero function — against the standing DSAI-avoidance rule; Meta needs raw bytes/URLs, not embeddings | 2026-07-19 |
15. Open Questions
| # | Type | Question | Owner | Deadline |
|---|---|---|---|---|
| 1 | Open Question | Partial-sync policy at go-live: can an agent be turned ON while some sources show Failed, or is a clean sync required? (Wireframe flags both options) | Dimas F | Gate 1 |
| 2 | Open Question | Suggested-agent heuristic when multiple AI agents exist in the org — most recently published, or explicit pick only? | Dimas F + Design | Figma delivery |
| 3 | Skills is a CRUD collection, not one blob: per skill title ≤64 (lowercase/numbers/hyphens), description ≤1,024, body ≤20,000 chars (docs v2.0.0). Each Qontak capability maps to one skill; save-time validation blocks over-limit text (S08 ERR-1) | — | — | |
| 4 | Open Question (narrowed 2026-07-18) | Files resolved: ≤100 MB, PDF/DOC/DOCX/PNG/JPG/JPEG (+CSV/XLSX gated — OQ-7). Still undocumented: FAQ count, website count, allowlist size — informs sync batching | Chatbot tech lead | RFC |
| 5 | Risk | Meta changes management API shapes between pilot and GA — Mitigation: phase is gated on GA (Dependency 2); contract tests pinned to the GA API version before Stage 0 | Chatbot squad | Stage 0 |
| 6 | Open Question | Eligibility API returns only is_eligible (no reason field, docs v2.0.0) — what "why not eligible" guidance do we render? Current plan: Meta's published criteria as static guidance; ask partner manager whether a reason surface is coming | Dimas F via Meta partner manager | Gate 1 |
| 7 | Open Question | CSV/XLSX knowledge files are "when enabled" in Meta's docs — enabled per-WABA, per-app, or per-capability? Determines whether the File upload mapping needs a format gate | Chatbot tech lead | RFC |
| 8 | Open Question | Should the Qontak agent later consume the S09 Business info source too (shared structured facts), or does it stay Meta-only? | Dimas F | Post-beta |
PRD CHANGELOG
| Version | Date | By | Section | Type | Summary |
|---|---|---|---|---|---|
| 1.0 | 2026-07-08 | Claude | All | CREATED | Initial Phase 2 PRD created from the MBA strategic-response grounding; drafted ahead of its GA gate per PM instruction (gate recorded in Header + Dependencies). |
| 1.1 | 2026-07-08 | Claude | Header, 6, 8 | MODIFIED | Embedded the channel-section and Resources "Meta sync" wireframes (wireframes/phase-2-*.svg) in §6; Header Figma line and story Mockup cells now link them. |
| 1.2 | 2026-07-08 | Claude | 8 | MODIFIED | Added the System-flow sequence diagram (mermaid) to §8, transcribing the numbered flow incl. all three failure branches (per score-prd 14a.5). |
| 1.3 | 2026-07-18 | Claude | Header, Phase Context, 2, Scope, 5, 6, 7, 8, 10, 11, 12, 14 + wireframe | MODIFIED | Added the per-source Meta-sync scope choice (PM requirement: admin chooses whether each knowledge source is for MBA or Qontak-only): new story MBA2-S06 + mba_sync_enabled (default ON) + "Off" status, S03/AC-1 scoped to enabled sources, sync/flow/observability/metrics/Gate-1 updated, decisions + rejected alternatives recorded, Resources wireframe gains the toggle + an Off-row example. Anchor Phase-2 goal wording aligned in the same change. |
| 1.4 | 2026-07-18 | Claude | Header, 4, Scope, 5, 6, 7, 8, 10, 14, 15 | MODIFIED | API-grounding vs Meta MBA docs v2.0.0 + side-by-side model (§7 Meta API surface & build map): new stories MBA2-S07 (audience + follow-up), S08 (per-field Profile Meta overrides), S09 (Business info source); settings full-replace + new-threads-only re-enable noted; Skills = CRUD collection w/ 64/1,024/20,000 limits (OQ-3 resolved); file limits recorded (OQ-4 narrowed); eligibility reason gap (OQ-6) + CSV/XLSX gate (OQ-7) + Business-info consumption (OQ-8) opened; per-item Meta-id sync reconciliation specced; coexistence constraint + divergence decisions recorded; S01-NEG rescoped to authoring fields. |
| 1.5 | 2026-07-18 | Claude | Header, 7 | MODIFIED | Standalone API-inventory doc dissolved into the Phase PRDs per PM instruction: §7 gains this phase's "Meta API surface & build map" table (Eligibility, Onboarding, Settings, Allowlist, Skills, Business Info, FAQs, Websites, Files). |
| 1.6 | 2026-07-19 | Claude | Header, Scope, 5, 7, 14 | MODIFIED | PM requirement: zero Mekari AI Services dependency in the MBA path — new §5 constraint + §7 pipeline-independence note; Files build row now specifies streaming the Qontak-owned OSS object as multipart binary to Meta (code-verified: AiKnowledgeSource.data holds the OSS object, SyncToAiService only hands a URL to AI Services); decision + rejected alternative recorded. |
| 1.7 | 2026-07-19 | Claude | Header, 4, Scope, 6, 7, 8, 14 + wireframe | MODIFIED | ground-prd fixes (all Confirmed P0/P1): sync re-anchored on the V2 save/update flow (create/update_ai_agent.rb:61; AiAgentHistory claim removed — V1 is disjoint); source-type mapping corrected to the real V2 enum file/url/text/api/ocr (OCR→Files, API→Not syncable; "Conversation history" removed — ChatbotGpt-only); handoff message = Meta default per PM decision (routing exits have no message field); FE targets named (hub-chat WhatsAppDetailPage, modules/ai-knowledge AI resources with real columns, V2 AiAgentEditor + change-highlight anchor); Resources wireframe realigned (columns, summary strip, API row). |
| 1.8 | 2026-07-19 | Claude | 8 | MODIFIED | Mermaid parse fix: semicolons in sequence-diagram message text broke rendering (replaced with em dashes); diagram now validates with mmdc. |