{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "31ad4b80",
   "metadata": {},
   "source": [
    "# Pelorus Demand Coverage Audit\n",
    "\n",
    "This notebook shows how to use the read-only `client.analysis()` surface to pull intent and cluster data from Pelorus, then analyze it with NumPy and Pandas.\n",
    "\n",
    "The default run uses a small sample payload so the notebook is executable without a running engine. To use a live Pelorus engine, set `USE_LIVE_ENGINE = True` in the setup cell and point `ENGINE_URL` / `DATASET` at your environment."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "d093d809",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:24.627804Z",
     "iopub.status.busy": "2026-07-02T14:16:24.625797Z",
     "iopub.status.idle": "2026-07-02T14:16:27.119971Z",
     "shell.execute_reply": "2026-07-02T14:16:27.119971Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "pd.set_option(\"display.max_colwidth\", 90)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ef25a302",
   "metadata": {},
   "source": [
    "## Connect or load sample data\n",
    "\n",
    "Set `USE_LIVE_ENGINE = True` to pull from Pelorus:\n",
    "\n",
    "```python\n",
    "from pelorus import PelorusClient\n",
    "pq = PelorusClient.connect(ENGINE_URL)\n",
    "analysis = pq.analysis()\n",
    "snapshot = analysis.snapshot(dataset=DATASET)\n",
    "intent_map = analysis.intent_map(dataset=DATASET)\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "98bc4234",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:27.128023Z",
     "iopub.status.busy": "2026-07-02T14:16:27.125499Z",
     "iopub.status.idle": "2026-07-02T14:16:27.158095Z",
     "shell.execute_reply": "2026-07-02T14:16:27.157088Z"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loaded 10 intent points and 3 cluster centroids\n"
     ]
    }
   ],
   "source": [
    "USE_LIVE_ENGINE = False\n",
    "ENGINE_URL = \"http://127.0.0.1:9090\"\n",
    "DATASET = \"support\"\n",
    "\n",
    "sample_intent_map = {\n",
    "    \"points\": [\n",
    "        {\"intent_id\": \"i-001\", \"intent_text\": \"how do I return an order\", \"hit_count\": 22, \"x\": -2.0, \"y\": 1.2, \"cluster_id\": 0, \"defined_cluster_id\": \"c-returns\", \"is_cluster_member\": True, \"status\": \"found\"},\n",
    "        {\"intent_id\": \"i-002\", \"intent_text\": \"refund timeline after cancellation\", \"hit_count\": 17, \"x\": -1.7, \"y\": 1.0, \"cluster_id\": 0, \"defined_cluster_id\": \"c-returns\", \"is_cluster_member\": True, \"status\": \"found\"},\n",
    "        {\"intent_id\": \"i-003\", \"intent_text\": \"where do invoices live\", \"hit_count\": 14, \"x\": 1.5, \"y\": 1.1, \"cluster_id\": 1, \"defined_cluster_id\": \"c-billing\", \"is_cluster_member\": True, \"status\": \"found\"},\n",
    "        {\"intent_id\": \"i-004\", \"intent_text\": \"change billing contact\", \"hit_count\": 9, \"x\": 1.8, \"y\": 1.3, \"cluster_id\": 1, \"defined_cluster_id\": \"c-billing\", \"is_cluster_member\": True, \"status\": \"partial\"},\n",
    "        {\"intent_id\": \"i-005\", \"intent_text\": \"transfer a license to another user\", \"hit_count\": 16, \"x\": 0.1, \"y\": -1.8, \"cluster_id\": 2, \"defined_cluster_id\": None, \"is_cluster_member\": False, \"status\": \"not_found\"},\n",
    "        {\"intent_id\": \"i-006\", \"intent_text\": \"seat reassignment rules\", \"hit_count\": 11, \"x\": 0.4, \"y\": -1.6, \"cluster_id\": 2, \"defined_cluster_id\": None, \"is_cluster_member\": False, \"status\": \"partial\"},\n",
    "        {\"intent_id\": \"i-007\", \"intent_text\": \"security review questionnaire\", \"hit_count\": 8, \"x\": 3.1, \"y\": -0.3, \"cluster_id\": -1, \"defined_cluster_id\": None, \"is_cluster_member\": False, \"status\": \"not_found\"},\n",
    "        {\"intent_id\": \"i-008\", \"intent_text\": \"SOC 2 report request\", \"hit_count\": 6, \"x\": 3.3, \"y\": -0.1, \"cluster_id\": -1, \"defined_cluster_id\": None, \"is_cluster_member\": False, \"status\": \"not_found\"},\n",
    "        {\"intent_id\": \"i-009\", \"intent_text\": \"cancel during trial\", \"hit_count\": 7, \"x\": -1.5, \"y\": 1.5, \"cluster_id\": 0, \"defined_cluster_id\": \"c-returns\", \"is_cluster_member\": True, \"status\": \"partial\"},\n",
    "        {\"intent_id\": \"i-010\", \"intent_text\": \"purchase order payment terms\", \"hit_count\": 5, \"x\": 1.2, \"y\": 0.8, \"cluster_id\": 1, \"defined_cluster_id\": \"c-billing\", \"is_cluster_member\": True, \"status\": \"found\"},\n",
    "    ],\n",
    "    \"cluster_centroids\": [\n",
    "        {\"cluster_id\": \"c-returns\", \"name\": \"Returns and refunds\", \"hit_count\": 46, \"x\": -1.75, \"y\": 1.2, \"threshold\": 0.78, \"use_classifier\": False, \"negative\": False},\n",
    "        {\"cluster_id\": \"c-billing\", \"name\": \"Billing operations\", \"hit_count\": 28, \"x\": 1.5, \"y\": 1.0, \"threshold\": 0.74, \"use_classifier\": False, \"negative\": False},\n",
    "        {\"cluster_id\": \"c-gap-security\", \"name\": \"Security docs gap\", \"hit_count\": 14, \"x\": 3.2, \"y\": -0.2, \"threshold\": 0.70, \"use_classifier\": False, \"negative\": True},\n",
    "    ],\n",
    "}\n",
    "\n",
    "sample_snapshot = {\n",
    "    \"projections\": sample_intent_map,\n",
    "    \"overlaps\": [\n",
    "        {\"cluster_a\": \"c-returns\", \"cluster_b\": \"c-billing\", \"strength\": 0.08, \"relation\": \"partial\"},\n",
    "        {\"cluster_a\": \"c-billing\", \"cluster_b\": \"c-gap-security\", \"strength\": 0.23, \"relation\": \"partial\"},\n",
    "    ],\n",
    "    \"coverage\": {\n",
    "        \"clusters\": {\n",
    "            \"c-returns\": {\"covered_intent_count\": 3, \"member_count\": 3},\n",
    "            \"c-billing\": {\"covered_intent_count\": 3, \"member_count\": 3},\n",
    "            \"c-gap-security\": {\"covered_intent_count\": 2, \"member_count\": 0},\n",
    "        }\n",
    "    },\n",
    "    \"backlog_counts\": {\"pending\": 4, \"processing\": 1, \"completed\": 18},\n",
    "}\n",
    "\n",
    "if USE_LIVE_ENGINE:\n",
    "    from pelorus import PelorusClient\n",
    "\n",
    "    pq = PelorusClient.connect(ENGINE_URL)\n",
    "    analysis = pq.analysis()\n",
    "    snapshot = analysis.snapshot(dataset=DATASET)\n",
    "    intent_map = analysis.intent_map(dataset=DATASET)\n",
    "else:\n",
    "    snapshot = sample_snapshot\n",
    "    intent_map = sample_intent_map\n",
    "\n",
    "points = pd.DataFrame(intent_map.get(\"points\", []))\n",
    "centroids = pd.DataFrame(intent_map.get(\"cluster_centroids\", []))\n",
    "overlaps = pd.DataFrame(snapshot.get(\"overlaps\", []))\n",
    "\n",
    "print(f\"Loaded {len(points)} intent points and {len(centroids)} cluster centroids\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "5683cdae",
   "metadata": {},
   "source": [
    "## High-demand intents without defined cluster coverage\n",
    "\n",
    "These are good candidates for curation. They represent repeated demand that has not yet been turned into a defined cluster."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "a90cff7a",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:27.164632Z",
     "iopub.status.busy": "2026-07-02T14:16:27.164632Z",
     "iopub.status.idle": "2026-07-02T14:16:27.212413Z",
     "shell.execute_reply": "2026-07-02T14:16:27.210413Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>intent_id</th>\n",
       "      <th>intent_text</th>\n",
       "      <th>hit_count</th>\n",
       "      <th>status</th>\n",
       "      <th>cluster_id</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>i-005</td>\n",
       "      <td>transfer a license to another user</td>\n",
       "      <td>16</td>\n",
       "      <td>not_found</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>i-006</td>\n",
       "      <td>seat reassignment rules</td>\n",
       "      <td>11</td>\n",
       "      <td>partial</td>\n",
       "      <td>2</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>i-007</td>\n",
       "      <td>security review questionnaire</td>\n",
       "      <td>8</td>\n",
       "      <td>not_found</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>i-008</td>\n",
       "      <td>SOC 2 report request</td>\n",
       "      <td>6</td>\n",
       "      <td>not_found</td>\n",
       "      <td>-1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  intent_id                         intent_text  hit_count     status  \\\n",
       "4     i-005  transfer a license to another user         16  not_found   \n",
       "5     i-006             seat reassignment rules         11    partial   \n",
       "6     i-007       security review questionnaire          8  not_found   \n",
       "7     i-008                SOC 2 report request          6  not_found   \n",
       "\n",
       "   cluster_id  \n",
       "4           2  \n",
       "5           2  \n",
       "6          -1  \n",
       "7          -1  "
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "required_columns = {\"hit_count\", \"is_cluster_member\", \"intent_text\", \"status\"}\n",
    "missing = required_columns - set(points.columns)\n",
    "if missing:\n",
    "    raise ValueError(f\"Intent map is missing expected columns: {sorted(missing)}\")\n",
    "\n",
    "uncovered = (\n",
    "    points[(points[\"hit_count\"] >= 5) & (~points[\"is_cluster_member\"].astype(bool))]\n",
    "    .sort_values(\"hit_count\", ascending=False)\n",
    "    [[\"intent_id\", \"intent_text\", \"hit_count\", \"status\", \"cluster_id\"]]\n",
    ")\n",
    "uncovered"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2bbbdd92",
   "metadata": {},
   "source": [
    "## Cluster cohesion in map space\n",
    "\n",
    "For each defined cluster, compute the average 2D distance from member intents to the cluster centroid. This is not a replacement for embedding-space validation, but it is useful for spotting diffuse or visually suspicious clusters in a demo/report."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "50664f14",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:27.216435Z",
     "iopub.status.busy": "2026-07-02T14:16:27.216435Z",
     "iopub.status.idle": "2026-07-02T14:16:27.249648Z",
     "shell.execute_reply": "2026-07-02T14:16:27.249648Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cluster_id</th>\n",
       "      <th>name</th>\n",
       "      <th>member_count</th>\n",
       "      <th>hit_count</th>\n",
       "      <th>mean_2d_distance</th>\n",
       "      <th>max_2d_distance</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>c-billing</td>\n",
       "      <td>Billing operations</td>\n",
       "      <td>3</td>\n",
       "      <td>28</td>\n",
       "      <td>0.294940</td>\n",
       "      <td>0.424264</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>c-returns</td>\n",
       "      <td>Returns and refunds</td>\n",
       "      <td>3</td>\n",
       "      <td>46</td>\n",
       "      <td>0.282223</td>\n",
       "      <td>0.390512</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>c-gap-security</td>\n",
       "      <td>Security docs gap</td>\n",
       "      <td>0</td>\n",
       "      <td>14</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "       cluster_id                 name  member_count  hit_count  \\\n",
       "1       c-billing   Billing operations             3         28   \n",
       "0       c-returns  Returns and refunds             3         46   \n",
       "2  c-gap-security    Security docs gap             0         14   \n",
       "\n",
       "   mean_2d_distance  max_2d_distance  \n",
       "1          0.294940         0.424264  \n",
       "0          0.282223         0.390512  \n",
       "2               NaN              NaN  "
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def cluster_cohesion(points_df, centroids_df):\n",
    "    rows = []\n",
    "    if points_df.empty or centroids_df.empty:\n",
    "        return pd.DataFrame(columns=[\"cluster_id\", \"name\", \"member_count\", \"hit_count\", \"mean_2d_distance\", \"max_2d_distance\"])\n",
    "\n",
    "    for centroid in centroids_df.to_dict(\"records\"):\n",
    "        cid = centroid[\"cluster_id\"]\n",
    "        members = points_df[points_df[\"defined_cluster_id\"] == cid]\n",
    "        if members.empty:\n",
    "            rows.append({\n",
    "                \"cluster_id\": cid,\n",
    "                \"name\": centroid.get(\"name\", cid),\n",
    "                \"member_count\": 0,\n",
    "                \"hit_count\": centroid.get(\"hit_count\", 0),\n",
    "                \"mean_2d_distance\": np.nan,\n",
    "                \"max_2d_distance\": np.nan,\n",
    "            })\n",
    "            continue\n",
    "        deltas = members[[\"x\", \"y\"]].to_numpy(dtype=float) - np.array([centroid[\"x\"], centroid[\"y\"]], dtype=float)\n",
    "        distances = np.linalg.norm(deltas, axis=1)\n",
    "        rows.append({\n",
    "            \"cluster_id\": cid,\n",
    "            \"name\": centroid.get(\"name\", cid),\n",
    "            \"member_count\": int(len(members)),\n",
    "            \"hit_count\": int(centroid.get(\"hit_count\", 0)),\n",
    "            \"mean_2d_distance\": float(distances.mean()),\n",
    "            \"max_2d_distance\": float(distances.max()),\n",
    "        })\n",
    "    return pd.DataFrame(rows).sort_values([\"mean_2d_distance\", \"hit_count\"], ascending=[False, False])\n",
    "\n",
    "cohesion = cluster_cohesion(points, centroids)\n",
    "cohesion"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "05cd5f59",
   "metadata": {},
   "source": [
    "## Overlap review\n",
    "\n",
    "Cluster overlaps can identify possible merge candidates or ambiguous boundaries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "5a0571cb",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:27.253169Z",
     "iopub.status.busy": "2026-07-02T14:16:27.253169Z",
     "iopub.status.idle": "2026-07-02T14:16:27.263858Z",
     "shell.execute_reply": "2026-07-02T14:16:27.263353Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>cluster_a</th>\n",
       "      <th>cluster_b</th>\n",
       "      <th>strength</th>\n",
       "      <th>relation</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>c-billing</td>\n",
       "      <td>c-gap-security</td>\n",
       "      <td>0.23</td>\n",
       "      <td>partial</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>c-returns</td>\n",
       "      <td>c-billing</td>\n",
       "      <td>0.08</td>\n",
       "      <td>partial</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   cluster_a       cluster_b  strength relation\n",
       "1  c-billing  c-gap-security      0.23  partial\n",
       "0  c-returns       c-billing      0.08  partial"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "if overlaps.empty:\n",
    "    overlap_review = pd.DataFrame(columns=[\"cluster_a\", \"cluster_b\", \"strength\", \"relation\"])\n",
    "else:\n",
    "    overlap_review = overlaps.sort_values(\"strength\", ascending=False)\n",
    "\n",
    "overlap_review"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0ec2f70f",
   "metadata": {},
   "source": [
    "## Simple priority score\n",
    "\n",
    "A quick NumPy score can combine uncovered demand, unresolved status, and distance from the map center. This is intentionally simple so teams can replace it with their own policy."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "88fcc6e3",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:27.266394Z",
     "iopub.status.busy": "2026-07-02T14:16:27.266394Z",
     "iopub.status.idle": "2026-07-02T14:16:27.287514Z",
     "shell.execute_reply": "2026-07-02T14:16:27.286506Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>intent_id</th>\n",
       "      <th>intent_text</th>\n",
       "      <th>hit_count</th>\n",
       "      <th>status</th>\n",
       "      <th>is_cluster_member</th>\n",
       "      <th>priority_score</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>i-005</td>\n",
       "      <td>transfer a license to another user</td>\n",
       "      <td>16</td>\n",
       "      <td>not_found</td>\n",
       "      <td>False</td>\n",
       "      <td>0.889268</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>i-006</td>\n",
       "      <td>seat reassignment rules</td>\n",
       "      <td>11</td>\n",
       "      <td>partial</td>\n",
       "      <td>False</td>\n",
       "      <td>0.699742</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>6</th>\n",
       "      <td>i-007</td>\n",
       "      <td>security review questionnaire</td>\n",
       "      <td>8</td>\n",
       "      <td>not_found</td>\n",
       "      <td>False</td>\n",
       "      <td>0.696149</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>i-008</td>\n",
       "      <td>SOC 2 report request</td>\n",
       "      <td>6</td>\n",
       "      <td>not_found</td>\n",
       "      <td>False</td>\n",
       "      <td>0.648991</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>i-001</td>\n",
       "      <td>how do I return an order</td>\n",
       "      <td>22</td>\n",
       "      <td>found</td>\n",
       "      <td>True</td>\n",
       "      <td>0.600000</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>i-002</td>\n",
       "      <td>refund timeline after cancellation</td>\n",
       "      <td>17</td>\n",
       "      <td>found</td>\n",
       "      <td>True</td>\n",
       "      <td>0.468737</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>i-003</td>\n",
       "      <td>where do invoices live</td>\n",
       "      <td>14</td>\n",
       "      <td>found</td>\n",
       "      <td>True</td>\n",
       "      <td>0.371369</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>i-004</td>\n",
       "      <td>change billing contact</td>\n",
       "      <td>9</td>\n",
       "      <td>partial</td>\n",
       "      <td>True</td>\n",
       "      <td>0.342833</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>i-009</td>\n",
       "      <td>cancel during trial</td>\n",
       "      <td>7</td>\n",
       "      <td>partial</td>\n",
       "      <td>True</td>\n",
       "      <td>0.308931</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>9</th>\n",
       "      <td>i-010</td>\n",
       "      <td>purchase order payment terms</td>\n",
       "      <td>5</td>\n",
       "      <td>found</td>\n",
       "      <td>True</td>\n",
       "      <td>0.138720</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "  intent_id                         intent_text  hit_count     status  \\\n",
       "4     i-005  transfer a license to another user         16  not_found   \n",
       "5     i-006             seat reassignment rules         11    partial   \n",
       "6     i-007       security review questionnaire          8  not_found   \n",
       "7     i-008                SOC 2 report request          6  not_found   \n",
       "0     i-001            how do I return an order         22      found   \n",
       "1     i-002  refund timeline after cancellation         17      found   \n",
       "2     i-003              where do invoices live         14      found   \n",
       "3     i-004              change billing contact          9    partial   \n",
       "8     i-009                 cancel during trial          7    partial   \n",
       "9     i-010        purchase order payment terms          5      found   \n",
       "\n",
       "   is_cluster_member  priority_score  \n",
       "4              False        0.889268  \n",
       "5              False        0.699742  \n",
       "6              False        0.696149  \n",
       "7              False        0.648991  \n",
       "0               True        0.600000  \n",
       "1               True        0.468737  \n",
       "2               True        0.371369  \n",
       "3               True        0.342833  \n",
       "8               True        0.308931  \n",
       "9               True        0.138720  "
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "xy = points[[\"x\", \"y\"]].to_numpy(dtype=float)\n",
    "center = xy.mean(axis=0)\n",
    "map_distance = np.linalg.norm(xy - center, axis=1)\n",
    "if map_distance.max() > 0:\n",
    "    map_distance = map_distance / map_distance.max()\n",
    "\n",
    "status_weight = points[\"status\"].map({\"not_found\": 1.0, \"partial\": 0.6, \"found\": 0.0}).fillna(0.3).to_numpy()\n",
    "uncovered_weight = (~points[\"is_cluster_member\"].astype(bool)).astype(float).to_numpy()\n",
    "hits = points[\"hit_count\"].to_numpy(dtype=float)\n",
    "hit_score = hits / max(hits.max(), 1.0)\n",
    "\n",
    "points = points.copy()\n",
    "points[\"priority_score\"] = 0.55 * hit_score + 0.30 * uncovered_weight + 0.15 * status_weight + 0.05 * map_distance\n",
    "priority = points.sort_values(\"priority_score\", ascending=False)[[\"intent_id\", \"intent_text\", \"hit_count\", \"status\", \"is_cluster_member\", \"priority_score\"]]\n",
    "priority.head(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "197c03d5",
   "metadata": {},
   "source": [
    "## Visualize the audit\n",
    "\n",
    "The plot highlights defined cluster members, uncovered intents, and negative/gap clusters."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "b3f48857",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:27.291529Z",
     "iopub.status.busy": "2026-07-02T14:16:27.290523Z",
     "iopub.status.idle": "2026-07-02T14:16:27.702722Z",
     "shell.execute_reply": "2026-07-02T14:16:27.702722Z"
    }
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAxUAAAHqCAYAAAByRmPvAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguNCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8fJSN1AAAACXBIWXMAAA9hAAAPYQGoP6dpAACMxUlEQVR4nO3dB3wURfsH8Ce9ExJCgEDoHWnSsVAEEZGmggoKSLEiIgiCIiiIiFgQG2ChKAoogqBIkSJKB0U60nuoSUiv9//8hnfvf3dckrtc7pLN/b7v597Lld2d3Ulwnp15ZjwMBoNBiIiIiIiI8skzvxsSERERERExqCAiIiIiIoexp4KIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKICsSAAQOkcuXKxeZqFrfzyYmHh4e88cYbhV0MKmAbN25UdYtnd/udJqLCwaCCyE3NnTtXNTq0h7+/v9SsWVOGDh0qly5dKuziEZGTJScnq4DSNPAgIsov73xvSUTFwsSJE6VKlSqSmpoqf/31l3z++eeycuVK2b9/vwQGBhZ28YiogHzxxReSnZ1tFlS8+eab6ue2bdvyOhORQxhUELm5zp07S9OmTdXPgwcPllKlSskHH3wgP//8szz22GOFUiY0fNLT01XvCZG9DAaDCpIDAgJ48Uz4+PjwehCR03D4ExGZad++vXo+efKk8b1vv/1WmjRpohpp4eHh8uijj8rZs2fzvHJJSUkycuRIiY6OFj8/P6lVq5a89957qtFnCsOvMOxqwYIFUq9ePfXdVatWWR0XDqdOnVLvYwiXJiYmRp588kmpUKGC2r5cuXLSvXt39d28LFu2TG677TYVxOB56dKlOQY706dPV2XEd8uUKSNPP/20xMbGmn0P49YfeOABVW4EbLhu9evXN57HTz/9pF5jH7iu//zzj9n2e/fuVePfq1atqr5TtmxZGThwoFy7ds3sexi6gutw7Ngx9f2SJUtKaGioug64C20qLS1NXnrpJSldurSEhIRIt27d5Ny5c2IrNNJxPAyRQ5lwfR988EE5fvy4XfWN69uuXTur17Z8+fLy8MMP5/t6r1692ni9Z82apT6bM2eO+p2OjIxUZapbt67qjbN2fJxfVFSU6qFDGQ8ePKj2jWtrKi4uToYPH248z+rVq8vUqVPNegFygmC9S5cu6jjYtlq1ajJp0iTJysq65Zwsj6v1KFj2KqAee/ToIUFBQeo8Uc+ob0umORX4u8DvAqC3QhsGyfwaIsov9lQQkRmtkYgeC5g8ebK8/vrr0rt3b9WTceXKFfn444/l7rvvVo1hNGStQUMSDdcNGzbIoEGDpFGjRqrRN2rUKDl//rx8+OGHZt9fv369LF68WAUXERERqvGDxputHnroITlw4IC88MILatvLly/L2rVr5cyZM7kmp65Zs0Zti8bmlClTVMNdC04soUGLQAafDxs2TAVen3zyiboOmzdvNrsTjIZ+nz591DaPP/64alx37dpVZs6cKa+++qo899xz6ns4Jq7tkSNHxNPz5n0elPvEiRPqOAgocF6zZ89Wz9u2bVONP1PYHkPYsK+///5bvvzyS9W4RENXg7pDcIgytW7dWl1vNG5tgQYvGu3r1q1TAeWLL74oCQkJqpwYJoeGsa31/cgjj6iGK4JAnJsGQ+8uXLig9p+f643rh541bDNkyBAV0AACCAQlKJu3t7esWLFCXXsEAM8//7xx+7Fjx8q7776r6qhTp07y77//qmcEU6YQrLVp00adE45VsWJF2bJli9r+4sWLKgjKDc4nODhYRowYoZ5RD+PHj5cbN27ItGnTxF4pKSlyzz33qN9zXCMEK998843ab24QUODaPPvss9KzZ08VIEKDBg3sLgMRkWIgIrc0Z84c3D42/P7774YrV64Yzp49a1i4cKGhVKlShoCAAMO5c+cMp06dMnh5eRkmT55stu2+ffsM3t7eZu/379/fUKlSJePrZcuWqf2/9dZbZts+/PDDBg8PD8OxY8eM7+F7np6ehgMHDph9d8OGDeozPJs6efKkeh/nALGxser1tGnT7L4OjRo1MpQrV84QFxdnfG/NmjVqf6bn8+eff6r3FixYYLb9qlWrbnkf2+G9LVu2GN9bvXq1eg/X9vTp08b3Z82adcs5Jicn31LO77//Xn1v06ZNxvcmTJig3hs4cKDZd3v27KnqUbNnzx71veeee87se3369FHvYz+5+frrr9X3Pvjgg1s+y87Otqu+jxw5or738ccfm30PZQsODjaee36uNz6zZO1adurUyVC1alXj65iYGPX73KNHD7PvvfHGG2q/+N3WTJo0yRAUFGT477//zL47ZswY9bdy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IyXDZWUjIiqOGFQQEVGxg/wJsWFtuWyDQT0zUZuIyDEMKoiIqNipVSZEvDw9JDUj91yJ2KR0NUSqZtlgl5WNiKg4YlBBRETFTuOKJaVSeKBcjE8Rw/96Iyxh2NP15HRpWbWURIb4u7yMRETFCYMKIiIqdjCcacAdVdQMT6evJ0t6ZvYtK2yfvJokVUoFycNNKhRaOYmIigsufkdERMVSk0phMqJjTfnyr5NyPjZF9UxgSBSe/bw9pX6FUBnarrpElQwo7KISEekegwoiIiq2mlYOl9vKh8rOU9fVtLHooQgL9JEmlW6+jyCDiIgcx6CCiIiKNX8fL7mrRmn1ICIi52BOBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBRERERERuVdQ8emnn0rlypXF399fWrRoITt27Mjxu3PnzhUPDw+zB7YjIiIiIiI3DSoWLVokI0aMkAkTJsjff/8tDRs2lE6dOsnly5dz3KZEiRJy8eJF4+P06dMuLTMRERERUXGnq6Digw8+kCFDhsiTTz4pdevWlZkzZ0pgYKB8/fXXOW6D3omyZcsaH2XKlHFpmYmIiIiIijtv0Yn09HTZvXu3jB071viep6endOjQQbZu3ZrjdomJiVKpUiXJzs6W22+/Xd5++22pV69ejt9PS0tTD82NGzfUs8FgUA9n047jimOR41hf+sG60hfWl36wrvTFHevLnc61MOkmqLh69apkZWXd0tOA14cPH7a6Ta1atVQvRoMGDSQ+Pl7ee+89ad26tRw4cEAqVKhgdZspU6bIm2++ecv72N5VQQUCIa2XhYo21pd+sK70hfWlH6wrfXHH+tJuEJNz6SaoyI9WrVqphwYBRZ06dWTWrFkyadIkq9ugJwR5G6a/iNHR0RIaGqryM5xNC1xwPHf5Y9cz1pd+sK70hfWlH6wrfXHH+nKX8yxsugkqIiIixMvLSy5dumT2Pl4jV8IWPj4+0rhxYzl2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KSoZ3RIWTHFVUKEloLvLojR6xvrSD9aVvrC+9IN1pS/uWF/aDWIqYkHFhg0bCuzgI0eOlAEDBuT6napVq6qcCExfayozM1PNCGVPvkSLFi3U87Fjx3IMKjBEasSIEWa/iNHR0WolRletqA3utNKlnrG+9IN1pS+sL/1gXemLO9aXu5ynLtepKCilS5dWj7y0atVK4uLiZPfu3dKkSRP13vr169UaGVqgYIs9e/aoZ/RY5MTPz089LGlT0rqC6RS4VPSxvvSDdaUvrC/9YF3pi7vVl7ucp26CigcffNCm7+WWr5BfderUkfvuu09ND4spbTGl7NChQ+XRRx81zvx0/vx5NbRp/vz50rx5czXECQnlmCGqVKlSatjWSy+9JHfffbfKBSEiIiIiIhcHFegmK0yYxQmBBAIHzPr00EMPyYwZM4yfI9BAErY2u5Ovr69KJp8+fbokJSWpIUzYZty4cYV4FkRERERExY+HgSnxuUJOBQIqJGq7KqcCx3KnsY56xvrSD9aVvrC+9IN1pS/uWF+ubsu5K7vXqSAiIiIiIjLFoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBzCoIKIiIiIiBhUEBERERFR4WFPBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBREREREROYRBBRERERERuUdQMXnyZGndurUEBgZKyZIlbdrGYDDI+PHjpVy5chIQECAdOnSQo0ePOr2sRERERETuRDdBRXp6uvTq1UueffZZm7d59913ZcaMGTJz5kzZvn27BAUFSadO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",
      "text/plain": [
       "<Figure size 800x500 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(figsize=(8, 5))\n",
    "\n",
    "covered = points[points[\"is_cluster_member\"].astype(bool)]\n",
    "uncovered_points = points[~points[\"is_cluster_member\"].astype(bool)]\n",
    "\n",
    "ax.scatter(covered[\"x\"], covered[\"y\"], s=covered[\"hit_count\"] * 12, alpha=0.65, label=\"Covered intents\")\n",
    "ax.scatter(uncovered_points[\"x\"], uncovered_points[\"y\"], s=uncovered_points[\"hit_count\"] * 16, marker=\"x\", color=\"#d97706\", label=\"Uncovered demand\")\n",
    "\n",
    "if not centroids.empty:\n",
    "    normal = centroids[~centroids.get(\"negative\", False).astype(bool)]\n",
    "    negative = centroids[centroids.get(\"negative\", False).astype(bool)]\n",
    "    ax.scatter(normal[\"x\"], normal[\"y\"], s=180, marker=\"D\", color=\"#2563eb\", label=\"Defined clusters\")\n",
    "    ax.scatter(negative[\"x\"], negative[\"y\"], s=220, marker=\"D\", color=\"#dc2626\", label=\"Negative/gap clusters\")\n",
    "    for row in centroids.to_dict(\"records\"):\n",
    "        ax.annotate(row.get(\"name\", row[\"cluster_id\"]), (row[\"x\"], row[\"y\"]), xytext=(5, 5), textcoords=\"offset points\", fontsize=9)\n",
    "\n",
    "for row in points.to_dict(\"records\"):\n",
    "    if row[\"priority_score\"] >= priority[\"priority_score\"].quantile(0.75):\n",
    "        ax.annotate(row[\"intent_id\"], (row[\"x\"], row[\"y\"]), xytext=(4, -10), textcoords=\"offset points\", fontsize=8)\n",
    "\n",
    "ax.set_title(\"Pelorus demand coverage audit\")\n",
    "ax.set_xlabel(\"Intent map x\")\n",
    "ax.set_ylabel(\"Intent map y\")\n",
    "ax.legend(loc=\"best\")\n",
    "ax.grid(True, alpha=0.2)\n",
    "plt.tight_layout()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "962ea347",
   "metadata": {},
   "source": [
    "## Report summary\n",
    "\n",
    "This is the kind of small report a team can run after a demo dataset has accumulated demand."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "ccb1fa4c",
   "metadata": {
    "execution": {
     "iopub.execute_input": "2026-07-02T14:16:27.706444Z",
     "iopub.status.busy": "2026-07-02T14:16:27.706444Z",
     "iopub.status.idle": "2026-07-02T14:16:27.715490Z",
     "shell.execute_reply": "2026-07-02T14:16:27.714483Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'intent_count': 10,\n",
       " 'defined_cluster_count': 3,\n",
       " 'uncovered_high_demand_count': 4,\n",
       " 'top_uncovered_intent': 'transfer a license to another user',\n",
       " 'highest_priority_intent': 'transfer a license to another user',\n",
       " 'active_backlog': 5}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "summary = {\n",
    "    \"intent_count\": int(len(points)),\n",
    "    \"defined_cluster_count\": int(len(centroids)),\n",
    "    \"uncovered_high_demand_count\": int(len(uncovered)),\n",
    "    \"top_uncovered_intent\": None if uncovered.empty else uncovered.iloc[0][\"intent_text\"],\n",
    "    \"highest_priority_intent\": None if priority.empty else priority.iloc[0][\"intent_text\"],\n",
    "    \"active_backlog\": int(sum(v for k, v in snapshot.get(\"backlog_counts\", {}).items() if k in {\"pending\", \"processing\", \"publishing\", \"failed\"} and isinstance(v, int))),\n",
    "}\n",
    "summary"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
