{"id":72840,"plugin_id":"plugin_asdk_app_6aa0148ae5b481918ed9dfdcc9944080","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-10-31T01:14:07.714Z","digest":"ea77685692738d053f9c81e8c4172cf19b9c107f94ab8c0ac43184eb72dc0221","against":null,"payload":{"description":"Audits all Chili Piper concierge routers for coverage gaps — unmapped lead sources, stale ownership rules, unbalanced distributions, and catch-all overflows — before they show up as lost pipeline","included_files":[{"relative_path":"references/api-reference.md","size_in_bytes":7639},{"relative_path":"references/audit-procedure.md","size_in_bytes":4823},{"relative_path":"references/output-format.md","size_in_bytes":2913}],"name":"routing-audit","skill_md_contents":"---\nname: routing-audit\ndescription: Audits all Chili Piper concierge routers for coverage gaps — unmapped lead sources, stale ownership rules, unbalanced distributions, and catch-all overflows — before they show up as lost pipeline\nversion: 0.2.10\napi_note: \"concierge-logs: optional page/pageSize pagination added (DISTRO-4576, max 100 per page, default 20); Step 4 and preflight updated to paginate for complete log coverage on high-volume routers. As of DISTRO-4549 (PR #898, 2026-06-18): routing.rules[] entries and routing.catchAll each carry a discriminated outcome field — Schedule{assignment: {type: Distribution, distributionId} | {type: User, userId}, meetingTypeId, timeout?: {minutes, onTimeout: Landing|{url}}, crmActions?: [...]} or Redirect{url}. Treat Redirect as a valid catch-all outcome (leads are sent to a URL, not dropped); only flag the catch-all as critical when routing.catchAll is absent or its outcome is null/missing. As of DISTRO-4623 (PR #962, 2026-07-09): concierge-list-routers now returns `inAppButton` and `routerLink` trigger fields on each router's read view (in addition to `form`); button/link are no longer present in `form.readOnlyTriggers`. Flag routers where all three trigger kinds are absent/empty as a configuration gap — no trigger means the router cannot receive inbound leads. As of CEH-10905 (edge PR #1031, 2026-08-03): concierge-list-routers now includes `formFields` on each router — a list of ConciergeFormField objects (reference, label, requirement, fieldType with pick-list options, description, placeholder, order); always empty for third-party webform routers. 2026-08-14 (CEH-11330, edge PR #1076): 13 MCP list tools now return {items: [...]} instead of bare top-level arrays — concierge-logs MCP response is {items: [...]}; paginate concierge-logs until items is empty or shorter than pageSize. 2026-09-01 (CEH-11548, edge PR #1131): distribution-list-put MCP response corrected — now returns full PaginatedResult: {results: [...], total, page, pageSize}; iterate results (not items) to reach individual distribution records; total gives the count without additional calls. 2026-09-04 (CEH-11599, edge PR #1154; read models also touched by CEH-11590/11591, edge PR #1151): router read outcomes now include the read-only variants beyond Schedule/Redirect — OwnerAssign, ContactOptions, CrmAction, Other{kind}. Schedule's crmActions? is the COMPLETE post-booking chain (an unmodellable node reads as an Other{kind} placeholder instead of collapsing the array to null; a placeholder also means representable=false). ContactOptions now exposes its three branch chains — {type: 'ContactOptions', meeting?, callSuccess?, callMissed?}, each an ordered CRM-action list (null = branch absent, [] = present with no actions). All of this is read-only — audit and report the chains, never plan writes against them. 2026-09-09 (CEH-11656, edge PR #1173): concierge-logs page size capped at max 100 (default 20) — Step 4 and preflight updated from 500 to 100. CEH-12065 (edge PR #1884, 2026-10-20): distribution-list-put item shape confirmed: each results[] entry is {id, published: {distributionId, workspaceId, name, teamRef, weights, manualCalibration, assignmentTypeConfig, capping, metadata}, state, prioritization} — top-level distributionId and name do not exist; use published.distributionId, published.name, and published.weights in Step 5.\"\nreferences:\n  - api-reference\n  - audit-procedure\n  - output-format\ninputs:\n  - name: workspace\n    type: string\n    description: \"Workspace name or ID to audit. Omit for org-wide audit of all workspaces.\"\n    required: false\n  - name: log_days\n    type: number\n    description: \"Number of days of concierge logs to analyze for catch-all overflow and no-match rates (max 30).\"\n    required: false\n    default: 7\noutputs:\n  - name: router_summary\n    description: All routers found with rule count, catch-all type, and recent no-match rate\n  - name: gaps\n    description: Specific routing gaps detected — stale rules, unbalanced distributions, high catch-all rates\n  - name: recommendations\n    description: Prioritized list of fixes with expected impact\ntools_required: [chili-piper-mcp]\nhuman_decision_point: \"Review gaps and decide which to fix first — routing gaps silently leak pipeline, so prioritize by volume before severity\"\nwrites_to: \"Nothing — read-only diagnostic. Use the Chili Piper router builder to apply fixes.\"\n---\n\n# Routing Audit\n\nYou are a RevOps systems auditor. Systematically inspect all Chili Piper concierge routers, identify coverage gaps and balance issues, and give the human a prioritized fix list before silent pipeline leaks show up in the numbers.\n\n> **Prefer live data over training.** MCP field names and tool signatures change. Load\n> `references/api-reference.md` before making MCP calls — it is the canonical field-name\n> truth for this skill (`concierge-logs` requires a routerId + has a 30-day max window;\n> per-router rules + catch-all come from the router object, not `rule-list`; etc.).\n\n## When to use\n\n- Someone wants a health check across all concierge routers before pipeline leaks surface.\n- Someone suspects leads are falling through to the catch-all or being dropped.\n- Someone wants to find stale ownership rules or unbalanced distributions.\n\n## Inputs\n\n| Input | Required | Default | What it controls |\n|-------|:--------:|---------|------------------|\n| `workspace` | — | all workspaces | Workspace name or ID to audit. Omit for an org-wide audit. |\n| `log_days` | — | `7` | Days of `concierge-logs` to analyze for catch-all overflow and no-match rates (max 30). |\n\nIf a required input is missing, ask for it in one sentence rather than guessing.\n\n## Process\n\n### Step 1 — Resolve workspace(s)\n\nIf `workspace` is specified, resolve its name to ID via `workspace-list`. If not, fetch\nall workspaces and audit each.\n\n```\ntool: workspace-list\nargs:\n  pagination:\n    page: 0\n    pageSize: 100\n```\n\nWorkspace items use `id` (NOT `workspaceId`) — use `workspace.id` when passing workspace\nIDs to subsequent calls. Field-name gotchas → `references/api-reference.md`\n§ Critical field name differences.\n\n### Step 2 — List all routers\n\nFor each workspace (using its `id`):\n\n```\ntool: concierge-list-routers\nargs:\n  workspaceId: <workspace.id>\n```\n\nFor each router store `routers[N].router.id` (routerId), `.name`, `.slug`,\n`routers[N].workspaceId`, and the routing config at `routers[N].router.routing`. Response\nshape → `references/api-reference.md` § concierge-list-routers — router object shape.\n\n### Step 3 — Inspect rules per router\n\nThe ordered rules (`router.routing.rules[]`) and the catch-all (`router.routing.catchAll`,\na separate object) are already on each router from Step 2. For richer rule detail across a\nworkspace, call `rule-list`. Confirm each catch-all has a valid `outcome` (`Schedule` or\n`Redirect` — flag as critical only when the catch-all is absent or has no outcome; surface\na `Redirect` catch-all as informational) and detect potentially stale rules. Full procedure\n→ `references/audit-procedure.md`\n§ Inspecting rules per router and § Detecting stale rules.\n\nAlso check trigger configuration: if `form`, `inAppButton`, and `routerLink` are all absent\nor empty on a router, flag it as a **[HIGH]** configuration gap — no trigger means the\nrouter cannot receive inbound leads. (`inAppButton` and `routerLink` are top-level fields\non the router object as of DISTRO-4623; they are no longer reported inside\n`form.readOnlyTriggers`.)\n\n### Step 4 — Analyze logs for catch-all overflow\n\nFor each router, pull `concierge-logs` over the `log_days` window and compute total leads,\ncatch-all rate (`matchedPath.route.type == \"CatchAllRoute\"`), and rule-match rate\n(`RuleRoute`). The tool returns at most 100 logs per page (default 20); paginate by incrementing `page`\nfrom 0 until `items` is empty or shorter than `pageSize` to capture all activity on\nhigh-volume routers (CEH-11330: MCP response is `{items: [...]}`, not a bare array). Full\nprocedure + flag thresholds → `references/audit-procedure.md`\n§ Analyzing logs for catch-all overflow. The 30-day limit + required `routerId` →\n`references/api-reference.md` § Hard API limits.\n\n### Step 5 — Check distribution balance\n\nFor each workspace, pull `distribution-list-put` and inspect active\nmembers, weights, handling, and assignment `statistics`. The MCP response is `{results: [...], total, page, pageSize}`\n— iterate `results` to reach each distribution record (CEH-11548; matches the HTTP endpoint shape). Each\nresults[] entry has shape `{id, published: {distributionId, workspaceId, name, teamRef, weights, manualCalibration, assignmentTypeConfig, capping, metadata}, state, prioritization}` — use\n`published.name`, `published.weights`, and `state.userStates[].statistics` (never top-level `name` or `distributionId`). Full procedure + flag thresholds\n→ `references/audit-procedure.md` § Checking distribution balance.\n\n### Step 6 — Output\n\nLead with the router summary, then gaps sorted by severity, then prioritized\nrecommendations. Exact layout → `references/output-format.md` § Report layout.\n\n## Preflight audit\n\nVerify before writing output:\n\n- [ ] Required inputs resolved (`workspace` → `id`, or all workspaces fetched).\n- [ ] Field names taken from `references/api-reference.md`, not guessed.\n- [ ] `concierge-logs` calls each pass `workspaceId` + `routerId`, span ≤ 30 days, and are paginated until `items` is empty or shorter than `pageSize`.\n- [ ] `log_days` respected (default 7, capped at 30).\n- [ ] Each catch-all checked for a valid `outcome` — `Schedule` or `Redirect` (critical only when absent/no outcome; `Redirect` surfaced as informational).\n- [ ] Each router checked for at least one active trigger (`form`, `inAppButton`, or `routerLink`); absence of all three flagged as [HIGH].\n- [ ] Distribution imbalance derived from `statistics.assigned` vs. configured weights; distribution name and id read from `published.name` / `published.distributionId`.\n\n## Checkpoint\n\nThis is a read-only diagnostic. Present the router summary, gaps (sorted by severity), and\nprioritized recommendations, then stop and let the human decide which gap to fix first —\nrouting gaps silently leak pipeline, so prioritize by volume before severity. All fixes\nare applied manually in the Chili Piper router builder.\n\n## Data handling\n\n- **PII present:** guest emails in concierge logs — used for counting only, not displayed\n- **Storage:** ephemeral — nothing persists after the skill completes\n- **Writes:** none — read-only. All fixes applied manually in the Chili Piper router builder.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}