collabSupport/services/voiceDiag/VOICE_PATH_ATTRIBUTION.md
jmcqueen 90a56c4640 Fix Prisma overlay tunnel discovery with site-scoped query_params.
Use topology/links and anynetlinks filters with eq/in operators so
store WAN follow-ups return real peer tunnels instead of unscoped dumps.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-28 09:01:40 -04:00

3.2 KiB

Prisma Phase 2 — Voice Path Attribution Discovery

Time-boxed discovery notes for "voice is on this tunnel" / per-handset attribution. Phase 1 (runtime waninterface status, overlay tunnels, app DPI by path_type) ships without these.

Confirmed Phase 1 surfaces (pan.dev + code)

Need Endpoint Notes
Circuit runtime status GET /sdwan/v2.1/api/sites/{siteId}/waninterfaces/{wiId}/status Wired in getWanInterfaceStatus
Overlay tunnels POST /sdwan/v2.0/api/topology/links/query with query_params.{source|target}_site_id.{in|eq} Preferred — includes status, peer names, vpnlinks[]
Anynet fallback POST /sdwan/v4.0/api/anynetlinks/query with query_params.ep{1|2}_site_id.{eq|in} Config rows; no runtime status
Voice DPI by path_type getAppMetric with filter.path_type=[VPN] etc. AppPerf* only; AppAudioMos omits path_type
Alarm → tunnel id info.vpn_reasons[].vpn_link_id extractVpnLinkIdsFromAlarmInfo

Live-tenant corrections (2026-07-28 / store 1005)

Issue Fix
limit: { count: N } → 400 "expected int" Topology/anynet limit is a bare int
query: { site_id: [...] } silently ignored Use query_params: { field: { eq|in: … } } (array under query_params → 400)
100 tunnels all peer — unknown Site-scoped topology query; resolve peer opposite local site; renderer collapses all-unknown
vpnlinks have no site fields Prefer topology links; anynet via ep1/ep2; never unscoped vpnlinks dump
Pairing down volume Prefer public-anynet; rank down/unknown first; cap ≤12; renderer shows ≤6
Cascading 429s Path-type breakout gated by PRISMA_VOICE_PATH_TYPE_BREAKOUT; status GETs capped

Probe recipes:

node scripts/prismaProbe.js wi-status <siteId> <wanInterfaceId>
node scripts/prismaProbe.js tunnels <siteId>
node scripts/prismaProbe.js app-by-path-type <siteId> <appId> --metric loss
node scripts/prismaProbe.js try-shapes app-by-path <siteId> <appId> <wiId>

Phase 2a candidates (probe before implementing further)

  1. App metrics + filter.path (waninterface id) — already supported in getAppMetric({ pathIds }) behind PRISMA_VOICE_PATH_ATTRIBUTION=1. Confirm live tenant accepts the filter (SCHEMA_CHECK_FAIL risk).

  2. Flow / session / app-path details — SCM UI "Application Path Details" HAR may reveal monitor endpoints that bind RTP to a specific path. Candidates: topology query v3.6, object_stats, app/wan contexts.

  3. Join keys to Webex — need client IP, subnet, or device id in Prisma flow records to map to Meraki/Webex handset inventory. Not confirmed.

Phase 2c status

attributeVoicePathToEndpoint() in services/callReport/voicePathAttribution.js returns null until a join key is confirmed. Path-level / path_type-level annotation is live via annotateWanWithPath().

Confidence language

Level Meaning
site Site-wide DPI only (siteLevelApprox: true)
path_type One path_type uniquely worse in window
path One waninterface uniquely worse (byPath)
endpoint Per-handset — not available without flow join keys