<?xml version="1.0" encoding="UTF-8"?>
<bpmn:definitions xmlns:bpmn="http://www.omg.org/spec/BPMN/20100524/MODEL"
  xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
  xmlns:dc="http://www.omg.org/spec/DD/20100524/DC"
  xmlns:zeebe="http://camunda.org/schema/zeebe/1.0"
  xmlns:di="http://www.omg.org/spec/DD/20100524/DI"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:modeler="http://camunda.org/schema/modeler/1.0"
  xmlns:bioc="http://bpmn.io/schema/bpmn/biocolor/1.0"
  id="Definitions_WealthOnboarding"
  targetNamespace="http://bpmn.io/schema/bpmn"
  exporter="Camunda Web Modeler"
  exporterVersion="e103445"
  modeler:executionPlatform="Camunda Cloud"
  modeler:executionPlatformVersion="8.9.0">

  <bpmn:message id="Message_CustomerConfirmation" name="customer_confirmation">
    <bpmn:extensionElements>
      <zeebe:subscription correlationKey="=correlationId" />
    </bpmn:extensionElements>
  </bpmn:message>

  <bpmn:process id="Wealth_Onboarding_Concierge" name="Wealth Onboarding Concierge (AG-UI)" isExecutable="true">

    <bpmn:documentation>
      END-TO-END WEALTH ONBOARDING — Camunda 8 orchestration across all 3 paths:

      PATH A — STP (Straight-Through Processing):
        AI agents run Intake → Identity → Risk → DMN → Investment Recommendation
        → Customer confirms → Account opens automatically. No human in the loop.

      PATH B — AI + Advisor (Hybrid / preferAdvisor=hybrid):
        Same AI pipeline. Risk Agent forces ADVISOR_REVIEW route via DMN (aumTier=PRIVATE_WEALTH).
        Customer sees preparation tips from concierge while advisor reviews.
        Advisor approves → Investment Recommendation → Customer confirms → Account opens.

      PATH C — Personal Advisor / Compliance Escalation:
        PEP/sanctions hit → COMPLIANCE_ESCALATION user task (MLRO review).
        Private wealth tier → ADVISOR_REVIEW user task.
        Human decides APPROVE / REJECT / ESCALATE.

      LONG-RUNNING LIFECYCLE:
        The Customer_Conversation BPMN runs as a parallel process for the entire onboarding.
        It auto-starts when the investment recommendation is ready and stays alive until account opens.
        The process pauses at Wait_CustomerConfirmation (message catch event) — the customer must
        explicitly confirm via the concierge or UI before the account is opened.
    </bpmn:documentation>

    <bpmn:startEvent id="Start_ApplicationSubmitted" name="Customer starts application">
      <bpmn:outgoing>flow_to_intake</bpmn:outgoing>
    </bpmn:startEvent>

    <bpmn:sequenceFlow id="flow_to_intake" sourceRef="Start_ApplicationSubmitted" targetRef="Task_IntakeAgent" />

    <bpmn:serviceTask id="Task_IntakeAgent" name="Intake Agent"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iIzdCM0ZCMyIvPjxwb2x5Z29uIHBvaW50cz0iMTYsNyAxNy44LDEzIDI0LDE0IDE5LDE4LjUgMjEuMiwyNS41IDE2LDIxLjUgMTAuOCwyNS41IDEzLDE4LjUgOCwxNCAxNC4yLDEzIiBmaWxsPSJ3aGl0ZSIvPjwvc3ZnPg==">
      <bpmn:documentation>AI Worker Agent — parses the application form, enriches from CRM, checks completeness. Streams TEXT_MESSAGE + TOOL_CALL AG-UI events live to the customer. Custom Zeebe worker (agent.intake).</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="agent.intake" retries="3" />
        <zeebe:ioMapping>
          <zeebe:output source="=intakeAgent.profile" target="customerProfile" />
          <zeebe:output source="=intakeAgent.completeness" target="intakeCompleteness" />
        </zeebe:ioMapping>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_to_intake</bpmn:incoming>
      <bpmn:outgoing>flow_to_identity</bpmn:outgoing>
    </bpmn:serviceTask>

    <bpmn:sequenceFlow id="flow_to_identity" sourceRef="Task_IntakeAgent" targetRef="Task_IdentityAgent" />

    <bpmn:serviceTask id="Task_IdentityAgent" name="Identity Verification Agent"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iIzE1NjVDMCIvPjxjaXJjbGUgY3g9IjE2IiBjeT0iMTIiIHI9IjQuNSIgZmlsbD0id2hpdGUiLz48cGF0aCBkPSJNNyAyNyBRNyAyMSAxNiAyMSBRMjUgMjEgMjUgMjciIGZpbGw9IndoaXRlIi8+PHJlY3QgeD0iMjAiIHk9IjkiIHdpZHRoPSI4IiBoZWlnaHQ9IjYiIHJ4PSIxIiBmaWxsPSIjOTBDQUY5Ii8+PGxpbmUgeDE9IjIxIiB5MT0iMTEiIHgyPSIyNyIgeTI9IjExIiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEiLz48bGluZSB4MT0iMjEiIHkxPSIxMyIgeDI9IjI1IiB5Mj0iMTMiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMSIvPjwvc3ZnPg==">
      <bpmn:documentation>AI Worker Agent — runs OFAC/EU/UN sanctions screening, PEP check, and document validation. Writes identityVerified, pepHit, sanctionsHit process variables. Custom Zeebe worker (agent.identity).</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="agent.identity" retries="3" />
        <zeebe:ioMapping>
          <zeebe:output source="=identityAgent.verified" target="identityVerified" />
          <zeebe:output source="=identityAgent.pepHit" target="pepHit" />
          <zeebe:output source="=identityAgent.sanctionsHit" target="sanctionsHit" />
        </zeebe:ioMapping>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_to_identity</bpmn:incoming>
      <bpmn:outgoing>flow_to_risk</bpmn:outgoing>
    </bpmn:serviceTask>

    <bpmn:sequenceFlow id="flow_to_risk" sourceRef="Task_IdentityAgent" targetRef="Task_RiskAgent" />

    <bpmn:serviceTask id="Task_RiskAgent" name="Risk Profile Agent"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iI0U2NTEwMCIvPjxwYXRoIGQ9Ik0xNiA3IEwyNSAyNCBMNyAyNCBaIiBmaWxsPSJ3aGl0ZSIgb3BhY2l0eT0iMC4yIi8+PHBhdGggZD0iTTE2IDggTDI0IDIzIEw4IDIzIFoiIGZpbGw9Im5vbmUiIHN0cm9rZT0id2hpdGUiIHN0cm9rZS13aWR0aD0iMS41Ii8+PGxpbmUgeDE9IjE2IiB5MT0iMTMiIHgyPSIxNiIgeTI9IjE5IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjIiLz48Y2lyY2xlIGN4PSIxNiIgY3k9IjIxLjUiIHI9IjEuMiIgZmlsbD0id2hpdGUiLz48L3N2Zz4=">
      <bpmn:documentation>AI Worker Agent — computes investor risk score (0-100), AUM tier (RETAIL/MASS_AFFLUENT/PRIVATE_WEALTH/ULTRA_HIGH_NET_WORTH), and investor class (GROWTH/BALANCED/INCOME). If preferAdvisor=true or hybrid, forces aumTier=PRIVATE_WEALTH so DMN rule r4 routes to ADVISOR_REVIEW. Custom Zeebe worker (agent.risk).</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="agent.risk" retries="3" />
        <zeebe:ioMapping>
          <zeebe:output source="=riskAgent.riskScore" target="riskScore" />
          <zeebe:output source="=riskAgent.aumTier" target="aumTier" />
          <zeebe:output source="=riskAgent.investorClass" target="investorClass" />
        </zeebe:ioMapping>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_to_risk</bpmn:incoming>
      <bpmn:outgoing>flow_to_routing</bpmn:outgoing>
    </bpmn:serviceTask>

    <bpmn:sequenceFlow id="flow_to_routing" sourceRef="Task_RiskAgent" targetRef="Decision_Routing" />

    <bpmn:businessRuleTask id="Decision_Routing" name="Route: STP / Advisor / Compliance"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iIzAxNTc5QiIvPjxwb2x5Z29uIHBvaW50cz0iMTYsOCAyNCwxNiAxNiwyNCA4LDE2IiBmaWxsPSJ3aGl0ZSIgb3BhY2l0eT0iMC45Ii8+PGxpbmUgeDE9IjEyIiB5MT0iMTYiIHgyPSIyMCIgeTI9IjE2IiBzdHJva2U9IiMwMTU3OUIiIHN0cm9rZS13aWR0aD0iMiIvPjxwb2x5Z29uIHBvaW50cz0iMTgsMTMgMjIsMTYgMTgsMTkiIGZpbGw9IiMwMTU3OUIiLz48L3N2Zz4=">
      <bpmn:documentation>DMN Business Rule Task — evaluates WealthRouting.dmn decision table. Rules: r1: sanctionsHit=true → COMPLIANCE_ESCALATION; r2: pepHit=true → COMPLIANCE_ESCALATION; r3: riskScore≥70 → ADVISOR_REVIEW; r4: aumTier=PRIVATE_WEALTH → ADVISOR_REVIEW; r5: catch-all → STP.</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:calledDecision decisionId="WealthRouting" resultVariable="routingDecision" />
      </bpmn:extensionElements>
      <bpmn:incoming>flow_to_routing</bpmn:incoming>
      <bpmn:outgoing>flow_to_gateway</bpmn:outgoing>
    </bpmn:businessRuleTask>

    <bpmn:sequenceFlow id="flow_to_gateway" sourceRef="Decision_Routing" targetRef="Gateway_Route" />

    <bpmn:exclusiveGateway id="Gateway_Route" name="Route?" default="flow_stp">
      <bpmn:incoming>flow_to_gateway</bpmn:incoming>
      <bpmn:outgoing>flow_advisor</bpmn:outgoing>
      <bpmn:outgoing>flow_compliance</bpmn:outgoing>
      <bpmn:outgoing>flow_stp</bpmn:outgoing>
    </bpmn:exclusiveGateway>

    <bpmn:sequenceFlow id="flow_advisor" name="ADVISOR_REVIEW" sourceRef="Gateway_Route" targetRef="Task_AdvisorReview">
      <bpmn:conditionExpression>=routingDecision = "ADVISOR_REVIEW"</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:sequenceFlow id="flow_compliance" name="COMPLIANCE_ESCALATION" sourceRef="Gateway_Route" targetRef="Task_ComplianceReview">
      <bpmn:conditionExpression>=routingDecision = "COMPLIANCE_ESCALATION"</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:sequenceFlow id="flow_stp" name="STP — fully automated" sourceRef="Gateway_Route" targetRef="Task_InvestmentAgent" />

    <bpmn:userTask id="Task_AdvisorReview" name="Advisor Review — risk &amp; suitability"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iI0I5OEMwMCIvPjxjaXJjbGUgY3g9IjE2IiBjeT0iMTEiIHI9IjQiIGZpbGw9IndoaXRlIi8+PHBhdGggZD0iTTggMjUgUTggMTkgMTYgMTkgUTI0IDE5IDI0IDI1IiBmaWxsPSJ3aGl0ZSIvPjxyZWN0IHg9IjE5IiB5PSIxOSIgd2lkdGg9IjkiIGhlaWdodD0iNyIgcng9IjEiIGZpbGw9IiNGRkQ1NEYiLz48bGluZSB4MT0iMjAiIHkxPSIyMS41IiB4Mj0iMjciIHkyPSIyMS41IiBzdHJva2U9IndoaXRlIiBzdHJva2Utd2lkdGg9IjEuNSIvPjxsaW5lIHgxPSIyMCIgeTE9IjI0IiB4Mj0iMjUiIHkyPSIyNCIgc3Ryb2tlPSJ3aGl0ZSIgc3Ryb2tlLXdpZHRoPSIxLjUiLz48L3N2Zz4=">
      <bpmn:documentation>HUMAN-IN-THE-LOOP (HITL) — Advisor review task. Surfaced to the advisor view as a UserTaskCard via AG-UI. Advisor sees customer risk profile, portfolio recommendation, and all KYC results. Decision: APPROVE (proceeds to investment), REJECT (application rejected), or ESCALATE (to compliance).</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:userTask />
        <zeebe:assignmentDefinition candidateGroups="Advisors" />
        <zeebe:formDefinition formId="form-advisor-review" />
        <zeebe:ioMapping>
          <zeebe:output source="=advisorDecision" target="advisorDecision" />
          <zeebe:output source="=advisorNotes" target="advisorNotes" />
        </zeebe:ioMapping>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_advisor</bpmn:incoming>
      <bpmn:outgoing>flow_advisor_decision</bpmn:outgoing>
    </bpmn:userTask>

    <bpmn:sequenceFlow id="flow_advisor_decision" sourceRef="Task_AdvisorReview" targetRef="Gateway_AdvisorDecision" />

    <bpmn:exclusiveGateway id="Gateway_AdvisorDecision" name="Advisor decision?" default="flow_advisor_approve">
      <bpmn:incoming>flow_advisor_decision</bpmn:incoming>
      <bpmn:outgoing>flow_advisor_approve</bpmn:outgoing>
      <bpmn:outgoing>flow_advisor_reject</bpmn:outgoing>
      <bpmn:outgoing>flow_advisor_escalate</bpmn:outgoing>
    </bpmn:exclusiveGateway>

    <bpmn:sequenceFlow id="flow_advisor_approve" name="APPROVE" sourceRef="Gateway_AdvisorDecision" targetRef="Task_InvestmentAgent" />
    <bpmn:sequenceFlow id="flow_advisor_reject" name="REJECT" sourceRef="Gateway_AdvisorDecision" targetRef="End_Rejected">
      <bpmn:conditionExpression>=advisorDecision = "REJECT"</bpmn:conditionExpression>
    </bpmn:sequenceFlow>
    <bpmn:sequenceFlow id="flow_advisor_escalate" name="ESCALATE" sourceRef="Gateway_AdvisorDecision" targetRef="Task_ComplianceReview">
      <bpmn:conditionExpression>=advisorDecision = "ESCALATE"</bpmn:conditionExpression>
    </bpmn:sequenceFlow>

    <bpmn:userTask id="Task_ComplianceReview" name="Compliance Review — MLRO &amp; sanctions"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iI0M2MjgyOCIvPjxwYXRoIGQ9Ik0xNiA3IEwyNCAxMC41IEwyNCAxNyBRMjQgMjMgMTYgMjcgUTggMjMgOCAxNyBMOCAxMC41IFoiIGZpbGw9IndoaXRlIiBvcGFjaXR5PSIwLjkiLz48bGluZSB4MT0iMTIiIHkxPSIxNyIgeDI9IjIwIiB5Mj0iMTciIHN0cm9rZT0iI0M2MjgyOCIgc3Ryb2tlLXdpZHRoPSIyIi8+PGNpcmNsZSBjeD0iMTYiIGN5PSIxMyIgcj0iMS41IiBmaWxsPSIjQzYyODI4Ii8+PGxpbmUgeDE9IjE2IiB5MT0iMTUiIHgyPSIxNiIgeTI9IjIxIiBzdHJva2U9IiNDNjI4MjgiIHN0cm9rZS13aWR0aD0iMiIvPjwvc3ZnPg==">
      <bpmn:documentation>HUMAN-IN-THE-LOOP (HITL) — MLRO compliance review. Triggered by PEP/sanctions flags (direct route) or advisor escalation. Compliance officer reviews full application, AML flags, and advisor notes. Decision: APPROVE (proceeds to investment) or REJECT (application rejected with audit trail).</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:userTask />
        <zeebe:assignmentDefinition candidateGroups="Compliance" />
        <zeebe:formDefinition formId="form-compliance-review" />
        <zeebe:ioMapping>
          <zeebe:output source="=complianceDecision" target="complianceDecision" />
        </zeebe:ioMapping>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_compliance</bpmn:incoming>
      <bpmn:incoming>flow_advisor_escalate</bpmn:incoming>
      <bpmn:outgoing>flow_after_compliance</bpmn:outgoing>
    </bpmn:userTask>

    <bpmn:sequenceFlow id="flow_after_compliance" sourceRef="Task_ComplianceReview" targetRef="Gateway_ComplianceDecision" />

    <bpmn:exclusiveGateway id="Gateway_ComplianceDecision" name="Compliance decision?" default="flow_compliance_approve">
      <bpmn:incoming>flow_after_compliance</bpmn:incoming>
      <bpmn:outgoing>flow_compliance_approve</bpmn:outgoing>
      <bpmn:outgoing>flow_compliance_reject</bpmn:outgoing>
    </bpmn:exclusiveGateway>

    <bpmn:sequenceFlow id="flow_compliance_approve" name="APPROVE" sourceRef="Gateway_ComplianceDecision" targetRef="Task_InvestmentAgent" />
    <bpmn:sequenceFlow id="flow_compliance_reject" name="REJECT" sourceRef="Gateway_ComplianceDecision" targetRef="End_Rejected">
      <bpmn:conditionExpression>=complianceDecision = "REJECT"</bpmn:conditionExpression>
    </bpmn:sequenceFlow>

    <bpmn:serviceTask id="Task_InvestmentAgent" name="Investment Recommendation Agent" zeebe:modelerTemplate="io.camunda.connectors.agenticai.aiagent.v1" zeebe:modelerTemplateVersion="6" zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPGNpcmNsZSBjeD0iMTYiIGN5PSIxNiIgcj0iMTYiIGZpbGw9IiNBNTZFRkYiLz4KPC9zdmc+">
      <bpmn:documentation>Official Camunda AI Agent Connector v6 (Bedrock/Claude Sonnet 4) — single-call task. Produces a model portfolio recommendation (GROWTH/BALANCED/INCOME) + rationale as structured JSON. Receives flow from STP path, advisor APPROVE, or compliance APPROVE. Downstream Task_EmitInvestmentCard reads agent.responseJson and auto-starts the Customer_Conversation BPMN.</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="io.camunda.agenticai:aiagent:1" retries="3" />
        <zeebe:ioMapping>
          <zeebe:input source="bedrock" target="provider.type" />
          <zeebe:input source="{{secrets.AWS_REGION}}" target="provider.bedrock.region" />
          <zeebe:input source="credentials" target="provider.bedrock.authentication.type" />
          <zeebe:input source="{{secrets.AWS_BEDROCK_ACCESS_KEY}}" target="provider.bedrock.authentication.accessKey" />
          <zeebe:input source="{{secrets.AWS_BEDROCK_SECRET_KEY}}" target="provider.bedrock.authentication.secretKey" />
          <zeebe:input source="us.anthropic.claude-sonnet-4-20250514-v1:0" target="provider.bedrock.model.model" />
          <zeebe:input source="=&quot;You are the wealth onboarding Investment Recommendation Agent for a private bank. Given a customer's risk profile, AUM tier, and investor class, you select an appropriate model portfolio and produce a one-paragraph rationale.&#10;&#10;Available model portfolios (pick exactly ONE):&#10;- GROWTH:   { equities: 80, fixedIncome: 10, alts: 10, label: 'Global Growth 80/10/10' }&#10;- BALANCED: { equities: 60, fixedIncome: 30, alts: 10, label: 'Balanced 60/30/10' }&#10;- INCOME:   { equities: 30, fixedIncome: 60, alts: 10, label: 'Income &amp;amp; Preservation 30/60/10' }&#10;&#10;Selection rules: investorClass=GROWTH -> GROWTH; investorClass=INCOME -> INCOME; otherwise BALANCED. Override if risk score / AUM tier strongly suggests otherwise.&#10;&#10;CRITICAL: Output ONLY a valid JSON object with exactly these fields. No prose outside the JSON. No markdown fences. {&#10;  &#92;&quot;portfolio&#92;&quot;: { &#92;&quot;label&#92;&quot;: string, &#92;&quot;equities&#92;&quot;: number, &#92;&quot;fixedIncome&#92;&quot;: number, &#92;&quot;alts&#92;&quot;: number, &#92;&quot;investorClass&#92;&quot;: string },&#10;  &#92;&quot;rationale&#92;&quot;: string (2-3 sentences, in the warm voice of a private banker)&#10;}&quot;" target="data.systemPrompt.prompt" />
          <zeebe:input source="=&quot;Customer: &quot; + customerProfile.fullName + &quot;&#10;Risk score: &quot; + string(riskScore) + &quot;/100&#10;AUM tier: &quot; + aumTier + &quot;&#10;Investor class: &quot; + investorClass + &quot;&#10;Stated objective: &quot; + (if is defined(customerProfile.investmentObjective) then customerProfile.investmentObjective else &quot;n/a&quot;) + &quot;&#10;Risk tolerance: &quot; + (if is defined(customerProfile.riskTolerance) then customerProfile.riskTolerance else &quot;n/a&quot;) + &quot;&#10;Investable assets: $&quot; + (if is defined(customerProfile.investableAssets) then string(customerProfile.investableAssets) else &quot;n/a&quot;) + &quot;&#10;&#10;Choose the portfolio and write the rationale.&quot;" target="data.userPrompt.prompt" />
          <zeebe:input source="in-process" target="data.memory.storage.type" />
          <zeebe:input source="=10" target="data.memory.contextWindowSize" />
          <zeebe:input source="=3" target="data.limits.maxModelCalls" />
          <zeebe:input source="text" target="data.response.format.type" />
          <zeebe:input source="=true" target="data.response.format.parseJson" />
          <zeebe:input source="=false" target="data.response.includeAssistantMessage" />
          <zeebe:input source="=true" target="data.response.includeAgentContext" />
          <zeebe:input source="=if is defined(agent) then agent.context else null" target="agentContext" />
        </zeebe:ioMapping>
        <zeebe:taskHeaders>
          <zeebe:header key="elementTemplateVersion" value="6" />
          <zeebe:header key="elementTemplateId" value="io.camunda.connectors.agenticai.aiagent.v1" />
          <zeebe:header key="resultVariable" value="agent" />
          <zeebe:header key="retryBackoff" value="PT2S" />
        </zeebe:taskHeaders>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_stp</bpmn:incoming>
      <bpmn:incoming>flow_advisor_approve</bpmn:incoming>
      <bpmn:incoming>flow_compliance_approve</bpmn:incoming>
      <bpmn:outgoing>flow_invest_to_emitter</bpmn:outgoing>
    </bpmn:serviceTask>

    <bpmn:sequenceFlow id="flow_invest_to_emitter" sourceRef="Task_InvestmentAgent" targetRef="Task_EmitInvestmentCard" />

    <bpmn:serviceTask id="Task_EmitInvestmentCard" name="Emit Recommendation Card + Start Conversation"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iIzE1NjVDMCIvPjxyZWN0IHg9IjgiIHk9IjEwIiB3aWR0aD0iMTYiIGhlaWdodD0iMTIiIHJ4PSIyIiBmaWxsPSJ3aGl0ZSIgb3BhY2l0eT0iMC45Ii8+PGxpbmUgeDE9IjExIiB5MT0iMTQiIHgyPSIyMSIgeTI9IjE0IiBzdHJva2U9IiMxNTY1QzAiIHN0cm9rZS13aWR0aD0iMS41Ii8+PGxpbmUgeDE9IjExIiB5MT0iMTciIHgyPSIxOCIgeTI9IjE3IiBzdHJva2U9IiMxNTY1QzAiIHN0cm9rZS13aWR0aD0iMS41Ii8+PHBvbHlnb24gcG9pbnRzPSIyMiwyMiAyNiwxNiAzMCwyMiIgZmlsbD0iIzRGQzNGNyIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoLTYsMCkiLz48L3N2Zz4=">
      <bpmn:documentation>Bridge worker — reads the structured JSON from the AI Agent Connector response, writes recommendedPortfolio + recommendationRationale to process variables, emits PortfolioRecommendationCard + ConfirmRecommendationCard AG-UI events. Also auto-starts the Customer_Conversation BPMN as a parallel long-running process for the customer. Custom Zeebe worker (onboarding.emitInvestmentCard).</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="onboarding.emitInvestmentCard" retries="2" />
        <zeebe:ioMapping>
          <zeebe:output source="=emitter.portfolio" target="recommendedPortfolio" />
          <zeebe:output source="=emitter.rationale" target="recommendationRationale" />
        </zeebe:ioMapping>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_invest_to_emitter</bpmn:incoming>
      <bpmn:outgoing>flow_invest_to_wait</bpmn:outgoing>
    </bpmn:serviceTask>

    <bpmn:sequenceFlow id="flow_invest_to_wait" sourceRef="Task_EmitInvestmentCard" targetRef="Wait_CustomerConfirmation" />

    <bpmn:intermediateCatchEvent id="Wait_CustomerConfirmation" name="Wait for customer to confirm">
      <bpmn:documentation>LONG-RUNNING PAUSE — process waits here indefinitely for a customer_confirmation message. The Customer_Conversation BPMN (started by Task_EmitInvestmentCard) runs in PARALLEL during this entire wait: the customer can chat, ask questions, explore alternatives, or bring in an advisor. When the customer explicitly confirms (or the concierge calls confirmAccountOpening), a customer_confirmation message is published — correlationKey=correlationId — and the process continues to open the account.</bpmn:documentation>
      <bpmn:incoming>flow_invest_to_wait</bpmn:incoming>
      <bpmn:outgoing>flow_wait_to_open</bpmn:outgoing>
      <bpmn:messageEventDefinition id="MsgEvent_CustomerConfirmation" messageRef="Message_CustomerConfirmation" />
    </bpmn:intermediateCatchEvent>

    <bpmn:sequenceFlow id="flow_wait_to_open" sourceRef="Wait_CustomerConfirmation" targetRef="Task_OpenAccount" />

    <bpmn:serviceTask id="Task_OpenAccount" name="Open Account in Core Banking"
      zeebe:modelerTemplateIcon="data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMzIiIGhlaWdodD0iMzIiIHZpZXdCb3g9IjAgMCAzMiAzMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48Y2lyY2xlIGN4PSIxNiIgY3k9IjE2IiByPSIxNiIgZmlsbD0iIzJFN0QzMiIvPjx0ZXh0IHg9IjE2IiB5PSIyMSIgdGV4dC1hbmNob3I9Im1pZGRsZSIgZmlsbD0id2hpdGUiIGZvbnQtc2l6ZT0iMTYiIGZvbnQtZmFtaWx5PSJzYW5zLXNlcmlmIiBmb250LXdlaWdodD0iYm9sZCI+JiMzNjs8L3RleHQ+PHJlY3QgeD0iNyIgeT0iMjIiIHdpZHRoPSIxOCIgaGVpZ2h0PSIzIiByeD0iMSIgZmlsbD0id2hpdGUiIG9wYWNpdHk9IjAuNyIvPjwvc3ZnPg==">
      <bpmn:documentation>Core banking integration — creates the investment account with the approved portfolio. Generates account number and emits RUN_FINISHED APPROVED to the AG-UI stream. Custom Zeebe worker (core.openAccount).</bpmn:documentation>
      <bpmn:extensionElements>
        <zeebe:taskDefinition type="core.openAccount" retries="3" />
        <zeebe:ioMapping>
          <zeebe:output source="=accountResult.accountNumber" target="accountNumber" />
        </zeebe:ioMapping>
      </bpmn:extensionElements>
      <bpmn:incoming>flow_wait_to_open</bpmn:incoming>
      <bpmn:outgoing>flow_to_end</bpmn:outgoing>
    </bpmn:serviceTask>

    <bpmn:sequenceFlow id="flow_to_end" sourceRef="Task_OpenAccount" targetRef="End_Approved" />

    <bpmn:endEvent id="End_Approved" name="Account opened — onboarding complete">
      <bpmn:incoming>flow_to_end</bpmn:incoming>
    </bpmn:endEvent>

    <bpmn:endEvent id="End_Rejected" name="Application rejected">
      <bpmn:incoming>flow_advisor_reject</bpmn:incoming>
      <bpmn:incoming>flow_compliance_reject</bpmn:incoming>
    </bpmn:endEvent>

    <!-- Artifacts must come after all flow elements per BPMN 2.0 XSD -->
    <bpmn:textAnnotation id="Annotation_ParallelConv">
      <bpmn:text>Customer_Conversation BPMN runs in parallel here — long-running chat concierge (4h timeout) answers questions, shows portfolio details, handles advisor escalations. Customer confirms → this process resumes.</bpmn:text>
    </bpmn:textAnnotation>
    <bpmn:association id="Assoc_Wait_ParallelConv" sourceRef="Wait_CustomerConfirmation" targetRef="Annotation_ParallelConv" associationDirection="None" />

  </bpmn:process>

  <bpmndi:BPMNDiagram id="BPMNDiagram_1">
    <bpmndi:BPMNPlane id="BPMNPlane_1" bpmnElement="Wealth_Onboarding_Concierge">

      <!-- Start event -->
      <bpmndi:BPMNShape id="Shape_Start_ApplicationSubmitted" bpmnElement="Start_ApplicationSubmitted"
        bioc:stroke="#1B5E20" bioc:fill="#C8E6C9">
        <dc:Bounds x="180" y="222" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="158" y="265" width="80" height="27" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>

      <!-- AI pipeline tasks — purple -->
      <bpmndi:BPMNShape id="Shape_Task_IntakeAgent" bpmnElement="Task_IntakeAgent"
        bioc:stroke="#7B3FB3" bioc:fill="#F3E5F5">
        <dc:Bounds x="270" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Shape_Task_IdentityAgent" bpmnElement="Task_IdentityAgent"
        bioc:stroke="#1565C0" bioc:fill="#E3F2FD">
        <dc:Bounds x="420" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Shape_Task_RiskAgent" bpmnElement="Task_RiskAgent"
        bioc:stroke="#E65100" bioc:fill="#FBE9E7">
        <dc:Bounds x="570" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>

      <!-- DMN — blue -->
      <bpmndi:BPMNShape id="Shape_Decision_Routing" bpmnElement="Decision_Routing"
        bioc:stroke="#01579B" bioc:fill="#E1F5FE">
        <dc:Bounds x="720" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>

      <!-- Route gateway -->
      <bpmndi:BPMNShape id="Shape_Gateway_Route" bpmnElement="Gateway_Route" isMarkerVisible="true">
        <dc:Bounds x="870" y="215" width="50" height="50" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="876" y="180" width="38" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>

      <!-- Advisor review — amber/gold HITL -->
      <bpmndi:BPMNShape id="Shape_Task_AdvisorReview" bpmnElement="Task_AdvisorReview"
        bioc:stroke="#F57F17" bioc:fill="#FFF8E1">
        <dc:Bounds x="1000" y="60" width="100" height="80" />
      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Shape_Gateway_AdvisorDecision" bpmnElement="Gateway_AdvisorDecision" isMarkerVisible="true">
        <dc:Bounds x="1150" y="75" width="50" height="50" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1141" y="40" width="68" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>

      <!-- Compliance review — red HITL -->
      <bpmndi:BPMNShape id="Shape_Task_ComplianceReview" bpmnElement="Task_ComplianceReview"
        bioc:stroke="#C62828" bioc:fill="#FFEBEE">
        <dc:Bounds x="1000" y="380" width="100" height="80" />
      </bpmndi:BPMNShape>

      <bpmndi:BPMNShape id="Shape_Gateway_ComplianceDecision" bpmnElement="Gateway_ComplianceDecision" isMarkerVisible="true">
        <dc:Bounds x="1150" y="395" width="50" height="50" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1138" y="455" width="74" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>

      <!-- AI Agent Connector (Bedrock) — deep purple -->
      <bpmndi:BPMNShape id="Shape_Task_InvestmentAgent" bpmnElement="Task_InvestmentAgent"
        bioc:stroke="#5C2D91" bioc:fill="#EDE7F6">
        <dc:Bounds x="1300" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>

      <!-- Emit card + start conversation — blue -->
      <bpmndi:BPMNShape id="Shape_Task_EmitInvestmentCard" bpmnElement="Task_EmitInvestmentCard"
        bioc:stroke="#1565C0" bioc:fill="#E8EAF6">
        <dc:Bounds x="1430" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>

      <!-- Long-running wait — teal -->
      <bpmndi:BPMNShape id="Shape_Wait_CustomerConfirmation" bpmnElement="Wait_CustomerConfirmation"
        bioc:stroke="#00796B" bioc:fill="#E0F7FA">
        <dc:Bounds x="1562" y="222" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1526" y="265" width="108" height="27" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>

      <!-- Core banking — green -->
      <bpmndi:BPMNShape id="Shape_Task_OpenAccount" bpmnElement="Task_OpenAccount"
        bioc:stroke="#2E7D32" bioc:fill="#E8F5E9">
        <dc:Bounds x="1640" y="200" width="100" height="80" />
      </bpmndi:BPMNShape>

      <!-- End approved — green -->
      <bpmndi:BPMNShape id="Shape_End_Approved" bpmnElement="End_Approved"
        bioc:stroke="#2E7D32" bioc:fill="#C8E6C9">
        <dc:Bounds x="1790" y="222" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1760" y="265" width="96" height="27" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>

      <!-- End rejected — red -->
      <bpmndi:BPMNShape id="Shape_End_Rejected" bpmnElement="End_Rejected"
        bioc:stroke="#C62828" bioc:fill="#FFCDD2">
        <dc:Bounds x="1790" y="542" width="36" height="36" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1763" y="585" width="90" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>

      <!-- Text annotation for parallel conversation -->
      <bpmndi:BPMNShape id="Shape_Annotation_ParallelConv" bpmnElement="Annotation_ParallelConv">
        <dc:Bounds x="1490" y="320" width="260" height="70" />
      </bpmndi:BPMNShape>

      <!-- Edges -->
      <bpmndi:BPMNEdge id="Edge_flow_to_intake" bpmnElement="flow_to_intake">
        <di:waypoint x="216" y="240" />
        <di:waypoint x="270" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_to_identity" bpmnElement="flow_to_identity">
        <di:waypoint x="370" y="240" />
        <di:waypoint x="420" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_to_risk" bpmnElement="flow_to_risk">
        <di:waypoint x="520" y="240" />
        <di:waypoint x="570" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_to_routing" bpmnElement="flow_to_routing">
        <di:waypoint x="670" y="240" />
        <di:waypoint x="720" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_to_gateway" bpmnElement="flow_to_gateway">
        <di:waypoint x="820" y="240" />
        <di:waypoint x="870" y="240" />
      </bpmndi:BPMNEdge>

      <!-- Advisor path — amber/gold color hint in label -->
      <bpmndi:BPMNEdge id="Edge_flow_advisor" bpmnElement="flow_advisor">
        <di:waypoint x="895" y="215" />
        <di:waypoint x="895" y="100" />
        <di:waypoint x="1000" y="100" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="905" y="143" width="90" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>

      <!-- Compliance path — red -->
      <bpmndi:BPMNEdge id="Edge_flow_compliance" bpmnElement="flow_compliance">
        <di:waypoint x="895" y="265" />
        <di:waypoint x="895" y="420" />
        <di:waypoint x="1000" y="420" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="905" y="333" width="120" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>

      <!-- STP path — fast lane -->
      <bpmndi:BPMNEdge id="Edge_flow_stp" bpmnElement="flow_stp">
        <di:waypoint x="920" y="240" />
        <di:waypoint x="1300" y="240" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1068" y="216" width="96" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Edge_flow_advisor_decision" bpmnElement="flow_advisor_decision">
        <di:waypoint x="1100" y="100" />
        <di:waypoint x="1150" y="100" />
      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Edge_flow_advisor_approve" bpmnElement="flow_advisor_approve">
        <di:waypoint x="1175" y="125" />
        <di:waypoint x="1175" y="200" />
        <di:waypoint x="1350" y="200" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1190" y="160" width="50" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_advisor_escalate" bpmnElement="flow_advisor_escalate">
        <di:waypoint x="1175" y="125" />
        <di:waypoint x="1175" y="340" />
        <di:waypoint x="1050" y="340" />
        <di:waypoint x="1050" y="380" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1080" y="320" width="60" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_advisor_reject" bpmnElement="flow_advisor_reject">
        <di:waypoint x="1200" y="100" />
        <di:waypoint x="1740" y="100" />
        <di:waypoint x="1740" y="560" />
        <di:waypoint x="1790" y="560" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1745" y="76" width="40" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Edge_flow_after_compliance" bpmnElement="flow_after_compliance">
        <di:waypoint x="1100" y="420" />
        <di:waypoint x="1150" y="420" />
      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Edge_flow_compliance_approve" bpmnElement="flow_compliance_approve">
        <di:waypoint x="1175" y="395" />
        <di:waypoint x="1175" y="280" />
        <di:waypoint x="1350" y="280" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1190" y="335" width="50" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_compliance_reject" bpmnElement="flow_compliance_reject">
        <di:waypoint x="1200" y="420" />
        <di:waypoint x="1740" y="420" />
        <di:waypoint x="1740" y="560" />
        <di:waypoint x="1790" y="560" />
        <bpmndi:BPMNLabel>
          <dc:Bounds x="1745" y="396" width="40" height="14" />
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>

      <bpmndi:BPMNEdge id="Edge_flow_invest_to_emitter" bpmnElement="flow_invest_to_emitter">
        <di:waypoint x="1400" y="240" />
        <di:waypoint x="1430" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_invest_to_wait" bpmnElement="flow_invest_to_wait">
        <di:waypoint x="1530" y="240" />
        <di:waypoint x="1562" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_wait_to_open" bpmnElement="flow_wait_to_open">
        <di:waypoint x="1598" y="240" />
        <di:waypoint x="1640" y="240" />
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="Edge_flow_to_end" bpmnElement="flow_to_end">
        <di:waypoint x="1740" y="240" />
        <di:waypoint x="1790" y="240" />
      </bpmndi:BPMNEdge>

      <!-- Association from wait event to annotation -->
      <bpmndi:BPMNEdge id="Edge_Assoc_Wait_ParallelConv" bpmnElement="Assoc_Wait_ParallelConv">
        <di:waypoint x="1580" y="258" />
        <di:waypoint x="1580" y="320" />
      </bpmndi:BPMNEdge>

    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</bpmn:definitions>
