Support Console — Operations Analyst SKILL
Base URL
Always read environment_access.md first. It overrides any localhost or 127.0.0.1 text in task prompts. The canonical base is the GDPEVO_ENV_BASE_URL from that file.
API Catalog & Error Convention
Catalog: GET /api/catalog lists all endpoints and record counts. Use for discovery.
Error convention: Missing/invalid records return {"error": "not_found"} with HTTP 200 — never a 404. Always check for the "error" key, not the HTTP status code.
Key endpoints:
| Endpoint |
Description |
/api/accounts/<id> |
Account status, auth, service_area, tier |
/api/tickets/<id> |
Ticket details incl. service_area, service_type, subscribed_mbps |
/api/diagnostics/<ticket_id> |
Pre-TS metrics, root_causes array |
/api/troubleshooting/<ticket_id> |
Post-TS metrics, steps taken |
/api/outages?service_area=<area> |
Active outages for a service area (empty [] if none) |
/api/cases/<id> |
Case metadata: customer_id, line_id, device_id, issue_type, customer_location |
/api/lines/<id> |
Line status, roaming, plan, suspension, data_used_gb |
/api/devices/<id> |
Device state: toggles, permissions, signal, SIM, VPN, network_mode |
/api/plans/<id> |
data_limit_gb, data_refueling_price_per_gb, monthly_price_usd |
/api/bills |
Full bill list; filter by customer_id match |
/api/customers |
Full customer list |
/api/enterprise/incidents/<id> |
Incident severity, owners, status, product |
/api/enterprise/export-runs?incident_id=<id> |
Export run history with failure_code and status |
/api/enterprise/messages?query=<text> |
Channel messages with author, body, channel |
/api/enterprise/sla/<ent_account_id> |
SLA credit triggers and percentages |
/api/enterprise/accounts |
Enterprise account owners and tiers |
Data Model Relationships
Ticket → Account (via account_id)
Ticket → Diagnostics (via ticket_id) → root_causes[]
Ticket → Troubleshooting (via ticket_id) → post_* metrics
Ticket → Outages (via service_area match)
Case → Line (via line_id)
Case → Device (via device_id)
Case → Customer (via customer_id)
Line → Plan (via plan_id)
Line → Bill (via customer_id match in /api/bills)
Incident → Enterprise Account (via enterprise_account_id)
Incident → Export Runs (via incident_id query)
Incident → Messages (via text query)
Incident → SLA (via enterprise_account_id)
Task Type 1: Ticket Batch Resolution
Input: CSV of ticket_ids with account_ids, service_type, customer_report.
Key question: For each ticket, determine resolution status, whether diagnostics are needed, which issues are present, and the resolution route.
Decision SOP
Fetch account by account_id.
{"error": "not_found"} → FAILED, INVALID_ACCOUNT, key_blocker=INVALID_ACCOUNT
status: "Suspended" → PENDING_ACTION, ACCOUNTS_PAYABLE, route=INELIGIBLE_ACCOUNT, key_blocker=OVERDUE_SUSPENSION
auth.last_login_status: "FAILURE" or auth.account_recovery_status: "FAILURE" → FAILED, key_blocker=AUTH_FAILED
status: "Active" and auth OK → continue
Fetch ticket by ticket_id for service_area and subscribed_mbps.
Check outages at /api/outages?service_area=<service_area>.
- Active outage matching the ticket's service_type →
PENDING_ACTION, route=OUTAGE_WAIT, key_blocker=ACTIVE_OUTAGE, escalation_team=NONE. Record the outage_id.
Fetch diagnostics by ticket_id.
diagnostic_needed: true if diagnostics record exists, false otherwise.
- latency_issue:
true when latency_ms > 100 (approximate threshold).
- bandwidth_issue:
true when bandwidth_mbps < 0.80 * subscribed_mbps.
- stability_issue:
true when jitter_ms > 35 or root_causes includes SIGNAL_LOSS.
Fetch troubleshooting by ticket_id.
- Compare
post_* metrics to pre-TS diagnostics.
- RESOLVED: Post-TS metrics show significant improvement toward subscribed levels (typically bandwidth ≥ 80% of subscribed, latency < 100ms) AND root cause is addressable by auto-TS (CONFIGURATION_DRIFT, VOICE_PROFILE_STALE).
- ESCALATED otherwise, with escalation team determined by root cause.
Root cause → escalation mapping:
| Root Cause |
Key Blocker |
Escalation Team |
FIBER_DROP_DAMAGE |
PHYSICAL_LINE_FAULT |
FIELD_OPS |
BACKBONE_CAPACITY |
NETWORK_CAPACITY |
NETWORK_ENGINEERING |
PROVISIONING_STALE |
PROVISIONING_STALE |
TIER2_SUPPORT |
CONFIGURATION_DRIFT (auto-resolved) |
NONE |
NONE |
VOICE_PROFILE_STALE (auto-resolved) |
NONE |
NONE |
SIGNAL_LOSS (+ FIBER_DROP_DAMAGE) |
PHYSICAL_LINE_FAULT |
FIELD_OPS |
GENERATED_NOISE (varies — check TS outcome) |
NONE or escalate by metrics |
NETWORK_ENGINEERING if bandwidth badly degraded |
Batch summary counts: RESOLVED, PENDING_ACTION, ESCALATED, FAILED, and tickets_requiring_customer_wait = count of PENDING_ACTION tickets.
Task Type 2: Mobile Contact-Center Queue
Input: JSON case queue with case_ids and reported_issues.
Key question: For each case, choose primary/secondary actions based on device, line, and bill state.
Decision SOP
Fetch case → get customer_id, line_id, device_id, issue_type, customer_location.
Fetch line → check status, roaming_enabled, plan_id, data_used_gb, suspension_reason.
Fetch device → check all toggles: sim_status, airplane_mode, mobile_data_enabled, data_saver_mode, phone_roaming_enabled, vpn_connected, network_mode_preference, can_send_mms, messaging_permissions, mmsc_url_present.
Fetch bill matching customer_id → check status (Paid vs Overdue), amount_due_usd.
Action decision tree (check in this order):
| Condition |
Primary Action |
Secondary Action |
Permission |
Final Route |
sim_status: "missing" (NO_SERVICE) |
RESEAT_SIM |
NO_ACTION |
NONE |
SELF_SERVICE |
Line status: "Suspended" + bill Overdue |
SEND_PAYMENT_REQUEST |
RESUME_LINE_REBOOT |
NONE |
BILLING_RECOVERY |
phone_roaming_enabled: false + abroad + line roaming on |
TOGGLE_ROAMING |
NO_ACTION |
NONE |
SELF_SERVICE |
Line roaming_enabled: false + abroad |
ENABLE_LINE_ROAMING |
NO_ACTION |
NONE |
CARRIER_UPDATE |
can_send_mms: false + missing storage permission |
GRANT_MESSAGING_PERMISSION |
NO_ACTION |
storage (or sms if that's missing) |
SELF_SERVICE |
vpn_connected: true + slow data |
DISCONNECT_VPN |
NO_ACTION |
NONE |
SELF_SERVICE |
data_saver_mode: true |
TOGGLE_DATA_SAVER |
NO_ACTION |
NONE |
SELF_SERVICE |
mobile_data_enabled: false |
TOGGLE_MOBILE_DATA |
NO_ACTION |
NONE |
SELF_SERVICE |
network_mode_preference: "3g_only" |
SET_NETWORK_MODE |
NO_ACTION |
NONE |
SELF_SERVICE |
| data_used_gb > plan limit |
REFUEL_DATA |
NO_ACTION |
NONE |
DATA_RECOVERY |
| No self-service fix possible |
TRANSFER_HUMAN |
NO_ACTION |
NONE |
HUMAN_TRANSFER |
Bill fields: bill_id and charge_amount_usd are populated only for billing-related actions (SEND_PAYMENT_REQUEST, REFUEL_DATA). Otherwise empty string and 0.00.
Permission field: Set to the specific missing permission (sms, storage, or sms_and_storage). Default NONE.
Queue summary: Count cases by final_route: self_service_fixes, billing_recoveries, carrier_updates, human_transfers.
Task Type 3: Enterprise Export Incident Response
Input: Client complaint email + response_requirements.json.
Key question: Build a structured response package with root cause, SLA credit, evidence, owners, and share permissions.
Decision SOP
Extract incident_id from the complaint email (e.g., INC-7301).
Fetch incident → get enterprise_account_id, severity, product, owners (engineering_owner, account_owner).
Fetch export runs via /api/enterprise/export-runs?incident_id=<id>:
- Identify the failure window: consecutive FAILED runs →
start_date, end_date, failed_days.
- Identify backfill: first SUCCEEDED run after failures →
backfill_days = count of SUCCEEDED backfill runs (not failed days).
- Extract root cause from
failure_code (e.g., STALE_CREDENTIAL).
Fetch messages via /api/enterprise/messages?query=<client_name>:
- Find the technical root cause message (usually from engineering_owner).
- Find the SLA/contract message (usually from account_owner, mentions credit percent).
channel_name: the message channel, lowercased with hyphens (as-is from API).
contributing_alert_issue: ARCHIVED_ALERT_ROUTE if channel name contains "archive", otherwise NONE or UNKNOWN.
Fetch SLA via /api/enterprise/sla/<enterprise_account_id> → monthly_export_credit_percent.
Fetch enterprise account for finance_owner and tier.
Naming conventions (from response_requirements):
channel_name: lowercase-hyphen channel name from messages.
evidence_folder: {client-lowercase-hyphen}-{YYYY-MM}-investigation (e.g., asteri-retail-2026-05-investigation).
report_title: {client-lowercase-hyphen}-export-failure-report.
Share permissions: Map from permission_users_to_include. Users matching finance_owner or account_owner typically get view. Order by the requirements list.
Response status:
NEEDS_FINANCE_REVIEW when SLA credit > 0% is involved.
NEEDS_ENGINEERING_REVIEW when root cause is unclear or backfill incomplete.
READY_TO_SEND when all evidence is clear, backfill confirmed, no credit issues.
UNDER_INVESTIGATION when incident status in API is unresolved and data is insufficient.
root_cause_category: Human-readable summary inferred from failure_code + message body (e.g., STALE_CREDENTIAL → "Stale Credential Rotation").
Task Type 4: Queue Quality Analysis (Pre-SLA Review)
Input: CSV of ticket_ids with account_ids, service_type, queue_note.
Key question: Classify each ticket by resolution status, route team, key blocker, and diagnostic requirement.
Decision SOP
Same initial flow as Task Type 1 (account → outage check → diagnostics → troubleshooting), but with a different answer schema focused on key_blocker and route_team rather than detailed issue flags.
Key differences from Task Type 1:
- When account is not found:
FAILED, NONE, INVALID_ACCOUNT.
- When auth has failed but account Active:
FAILED, NONE, AUTH_FAILED.
- Route team is
NONE when no escalation is needed (outage wait, invalid account, auth fail, auto-resolved).
- Queue summary includes counts per escalation team: TIER2_SUPPORT, FIELD_OPS, NETWORK_ENGINEERING, ACCOUNTS_PAYABLE.
Task Type 5: Mobile Data Recovery
Input: JSON worklist with case_ids + customer_preferences map.
Key question: Select primary/secondary actions, refuel amount, charge, carrier update flag, and route.
Decision SOP
Same device/line/bill inspection as Task Type 2, but focused on mobile data issues. Additional considerations:
Data refuel: When data_used_gb > plan.data_limit_gb:
- Read
customer_preferences[case_id].accepted_refuel_gb for the refuel amount.
charge_amount_usd = accepted_refuel_gb × plan.data_refueling_price_per_gb (rounded to 2 decimals).
data_refuel_gb: the accepted_refuel_gb value (1 decimal).
- If
does_not_want_plan_change: true, do not suggest a plan change; just refuel.
Carrier updates: When line-side settings need carrier action (e.g., ENABLE_LINE_ROAMING), carrier_update_required: true, route=CARRIER_UPDATE.
Device setting fixes: TOGGLE_MOBILE_DATA, TOGGLE_DATA_SAVER, SET_NETWORK_MODE, DISCONNECT_VPN → route=DEVICE_SETTING_FIX.
Worklist summary: Count per final_route plus total_estimated_customer_charge_usd (sum of all charge_amount_usd).
Common Pitfalls
Not checking outages first: Always query /api/outages?service_area=<area> BEFORE concluding on diagnostics. An active outage overrides all other analysis — the ticket becomes PENDING_ACTION / OUTAGE_WAIT.
Account status before diagnostics: A Suspended or auth-failed account makes diagnostics irrelevant. Check account status first.
Invalid account IDs in payload: Account IDs like BAD-XXXX return {"error": "not_found"} — don't assume the account exists just because the ticket CSV lists it.
Roaming mismatch: Distinguish device-side (phone_roaming_enabled) from line-side (roaming_enabled). Device toggle → TOGGLE_ROAMING; line toggle → ENABLE_LINE_ROAMING (carrier action).
MMS permissions: MMS requires both sms and storage device permissions. Check messaging_permissions object, not just can_send_mms.
Export backfill vs failure count: backfill_days = number of SUCCEEDED backfill runs, NOT the number of failed days. A single successful run after 3 failures = 1 backfill day.
Plan data limits: Always fetch the plan to get data_limit_gb — don't assume a fixed limit. Compare line.data_used_gb to plan.data_limit_gb.
Answer template order: Preserve payload order for ticket/case arrays. Sort by ascending case_id or payload order as specified in the template comments.
Numeric precision: charge_amount_usd always 2 decimal places; data_refuel_gb always 1 decimal place.
SLA credits trigger finance review: Any non-zero SLA credit percent means response_status should be NEEDS_FINANCE_REVIEW.
Field Value Quick Reference
Ticket resolutions
RESOLVED: Auto-TS fixed the issue (metrics improved to acceptable levels).
PENDING_ACTION: Waiting on outage resolution OR customer payment/action.
ESCALATED: Needs another team (FIELD_OPS, NETWORK_ENGINEERING, TIER2_SUPPORT).
FAILED: Unresolvable via support (INVALID_ACCOUNT, AUTH_FAILED).
Escalation teams
NONE: No team needed (auto-resolved, outage wait, or unfixable).
TIER2_SUPPORT: Configuration/provisioning issues beyond auto-TS.
FIELD_OPS: Physical damage (fiber, line faults).
NETWORK_ENGINEERING: Capacity/backbone issues.
ACCOUNTS_PAYABLE: Billing/suspension issues.
Mobile final routes
SELF_SERVICE: User can fix on device.
BILLING_RECOVERY: Overdue bill payment needed.
CARRIER_UPDATE: Line-side change needed.
HUMAN_TRANSFER: No self-service fix possible.
DATA_RECOVERY: Data refuel/plan change.
DEVICE_SETTING_FIX: Toggle or setting change on device.
1---2name: self-attempt-03-413description: Support Console — Operations Analyst SKILL4---5# Support Console — Operations Analyst SKILL67## Base URL89Always read `environment_access.md` first. It overrides any `localhost` or `127.0.0.1` text in task prompts. The canonical base is the `GDPEVO_ENV_BASE_URL` from that file.1011## API Catalog & Error Convention1213**Catalog**: `GET /api/catalog` lists all endpoints and record counts. Use for discovery.1415**Error convention**: Missing/invalid records return `{"error": "not_found"}` with HTTP 200 — never a 404. Always check for the `"error"` key, not the HTTP status code.1617**Key endpoints**:1819| Endpoint | Description |20|---|---|21| `/api/accounts/<id>` | Account status, auth, service_area, tier |22| `/api/tickets/<id>` | Ticket details incl. service_area, service_type, subscribed_mbps |23| `/api/diagnostics/<ticket_id>` | Pre-TS metrics, root_causes array |24| `/api/troubleshooting/<ticket_id>` | Post-TS metrics, steps taken |25| `/api/outages?service_area=<area>` | Active outages for a service area (empty `[]` if none) |26| `/api/cases/<id>` | Case metadata: customer_id, line_id, device_id, issue_type, customer_location |27| `/api/lines/<id>` | Line status, roaming, plan, suspension, data_used_gb |28| `/api/devices/<id>` | Device state: toggles, permissions, signal, SIM, VPN, network_mode |29| `/api/plans/<id>` | data_limit_gb, data_refueling_price_per_gb, monthly_price_usd |30| `/api/bills` | Full bill list; filter by customer_id match |31| `/api/customers` | Full customer list |32| `/api/enterprise/incidents/<id>` | Incident severity, owners, status, product |33| `/api/enterprise/export-runs?incident_id=<id>` | Export run history with failure_code and status |34| `/api/enterprise/messages?query=<text>` | Channel messages with author, body, channel |35| `/api/enterprise/sla/<ent_account_id>` | SLA credit triggers and percentages |36| `/api/enterprise/accounts` | Enterprise account owners and tiers |3738## Data Model Relationships3940```41Ticket → Account (via account_id)42Ticket → Diagnostics (via ticket_id) → root_causes[]43Ticket → Troubleshooting (via ticket_id) → post_* metrics44Ticket → Outages (via service_area match)4546Case → Line (via line_id)47Case → Device (via device_id)48Case → Customer (via customer_id)49Line → Plan (via plan_id)50Line → Bill (via customer_id match in /api/bills)5152Incident → Enterprise Account (via enterprise_account_id)53Incident → Export Runs (via incident_id query)54Incident → Messages (via text query)55Incident → SLA (via enterprise_account_id)56```5758## Task Type 1: Ticket Batch Resolution5960**Input**: CSV of ticket_ids with account_ids, service_type, customer_report.61**Key question**: For each ticket, determine resolution status, whether diagnostics are needed, which issues are present, and the resolution route.6263### Decision SOP64651. **Fetch account** by `account_id`.66 - `{"error": "not_found"}` → `FAILED`, `INVALID_ACCOUNT`, key_blocker=`INVALID_ACCOUNT`67 - `status: "Suspended"` → `PENDING_ACTION`, `ACCOUNTS_PAYABLE`, route=`INELIGIBLE_ACCOUNT`, key_blocker=`OVERDUE_SUSPENSION`68 - `auth.last_login_status: "FAILURE"` or `auth.account_recovery_status: "FAILURE"` → `FAILED`, key_blocker=`AUTH_FAILED`69 - `status: "Active"` and auth OK → continue70712. **Fetch ticket** by `ticket_id` for service_area and subscribed_mbps.72733. **Check outages** at `/api/outages?service_area=<service_area>`.74 - Active outage matching the ticket's service_type → `PENDING_ACTION`, route=`OUTAGE_WAIT`, key_blocker=`ACTIVE_OUTAGE`, escalation_team=`NONE`. Record the `outage_id`.75764. **Fetch diagnostics** by `ticket_id`.77 - `diagnostic_needed`: `true` if diagnostics record exists, `false` otherwise.78 - **latency_issue**: `true` when `latency_ms > 100` (approximate threshold).79 - **bandwidth_issue**: `true` when `bandwidth_mbps < 0.80 * subscribed_mbps`.80 - **stability_issue**: `true` when `jitter_ms > 35` or root_causes includes `SIGNAL_LOSS`.81825. **Fetch troubleshooting** by `ticket_id`.83 - Compare `post_*` metrics to pre-TS diagnostics.84 - **RESOLVED**: Post-TS metrics show significant improvement toward subscribed levels (typically bandwidth ≥ 80% of subscribed, latency < 100ms) AND root cause is addressable by auto-TS (CONFIGURATION_DRIFT, VOICE_PROFILE_STALE).85 - **ESCALATED** otherwise, with escalation team determined by root cause.86876. **Root cause → escalation mapping**:88 | Root Cause | Key Blocker | Escalation Team |89 |---|---|---|90 | `FIBER_DROP_DAMAGE` | `PHYSICAL_LINE_FAULT` | `FIELD_OPS` |91 | `BACKBONE_CAPACITY` | `NETWORK_CAPACITY` | `NETWORK_ENGINEERING` |92 | `PROVISIONING_STALE` | `PROVISIONING_STALE` | `TIER2_SUPPORT` |93 | `CONFIGURATION_DRIFT` (auto-resolved) | `NONE` | `NONE` |94 | `VOICE_PROFILE_STALE` (auto-resolved) | `NONE` | `NONE` |95 | `SIGNAL_LOSS` (+ FIBER_DROP_DAMAGE) | `PHYSICAL_LINE_FAULT` | `FIELD_OPS` |96 | `GENERATED_NOISE` (varies — check TS outcome) | `NONE` or escalate by metrics | `NETWORK_ENGINEERING` if bandwidth badly degraded |97987. **Batch summary** counts: RESOLVED, PENDING_ACTION, ESCALATED, FAILED, and `tickets_requiring_customer_wait` = count of PENDING_ACTION tickets.99100## Task Type 2: Mobile Contact-Center Queue101102**Input**: JSON case queue with case_ids and reported_issues.103**Key question**: For each case, choose primary/secondary actions based on device, line, and bill state.104105### Decision SOP1061071. **Fetch case** → get customer_id, line_id, device_id, issue_type, customer_location.1081092. **Fetch line** → check status, roaming_enabled, plan_id, data_used_gb, suspension_reason.1101113. **Fetch device** → check all toggles: sim_status, airplane_mode, mobile_data_enabled, data_saver_mode, phone_roaming_enabled, vpn_connected, network_mode_preference, can_send_mms, messaging_permissions, mmsc_url_present.1121134. **Fetch bill** matching customer_id → check status (Paid vs Overdue), amount_due_usd.1141155. **Action decision tree** (check in this order):116117 | Condition | Primary Action | Secondary Action | Permission | Final Route |118 |---|---|---|---|---|119 | `sim_status: "missing"` (NO_SERVICE) | `RESEAT_SIM` | `NO_ACTION` | `NONE` | `SELF_SERVICE` |120 | Line `status: "Suspended"` + bill Overdue | `SEND_PAYMENT_REQUEST` | `RESUME_LINE_REBOOT` | `NONE` | `BILLING_RECOVERY` |121 | `phone_roaming_enabled: false` + abroad + line roaming on | `TOGGLE_ROAMING` | `NO_ACTION` | `NONE` | `SELF_SERVICE` |122 | Line `roaming_enabled: false` + abroad | `ENABLE_LINE_ROAMING` | `NO_ACTION` | `NONE` | `CARRIER_UPDATE` |123 | `can_send_mms: false` + missing storage permission | `GRANT_MESSAGING_PERMISSION` | `NO_ACTION` | `storage` (or `sms` if that's missing) | `SELF_SERVICE` |124 | `vpn_connected: true` + slow data | `DISCONNECT_VPN` | `NO_ACTION` | `NONE` | `SELF_SERVICE` |125 | `data_saver_mode: true` | `TOGGLE_DATA_SAVER` | `NO_ACTION` | `NONE` | `SELF_SERVICE` |126 | `mobile_data_enabled: false` | `TOGGLE_MOBILE_DATA` | `NO_ACTION` | `NONE` | `SELF_SERVICE` |127 | `network_mode_preference: "3g_only"` | `SET_NETWORK_MODE` | `NO_ACTION` | `NONE` | `SELF_SERVICE` |128 | data_used_gb > plan limit | `REFUEL_DATA` | `NO_ACTION` | `NONE` | `DATA_RECOVERY` |129 | No self-service fix possible | `TRANSFER_HUMAN` | `NO_ACTION` | `NONE` | `HUMAN_TRANSFER` |1301316. **Bill fields**: `bill_id` and `charge_amount_usd` are populated only for billing-related actions (SEND_PAYMENT_REQUEST, REFUEL_DATA). Otherwise empty string and `0.00`.1321337. **Permission field**: Set to the specific missing permission (`sms`, `storage`, or `sms_and_storage`). Default `NONE`.1341358. **Queue summary**: Count cases by final_route: self_service_fixes, billing_recoveries, carrier_updates, human_transfers.136137## Task Type 3: Enterprise Export Incident Response138139**Input**: Client complaint email + response_requirements.json.140**Key question**: Build a structured response package with root cause, SLA credit, evidence, owners, and share permissions.141142### Decision SOP1431441. **Extract incident_id** from the complaint email (e.g., INC-7301).1451462. **Fetch incident** → get enterprise_account_id, severity, product, owners (engineering_owner, account_owner).1471483. **Fetch export runs** via `/api/enterprise/export-runs?incident_id=<id>`:149 - Identify the **failure window**: consecutive FAILED runs → `start_date`, `end_date`, `failed_days`.150 - Identify **backfill**: first SUCCEEDED run after failures → `backfill_days` = count of SUCCEEDED backfill runs (not failed days).151 - Extract **root cause** from `failure_code` (e.g., `STALE_CREDENTIAL`).1521534. **Fetch messages** via `/api/enterprise/messages?query=<client_name>`:154 - Find the technical root cause message (usually from engineering_owner).155 - Find the SLA/contract message (usually from account_owner, mentions credit percent).156 - `channel_name`: the message channel, lowercased with hyphens (as-is from API).157 - `contributing_alert_issue`: `ARCHIVED_ALERT_ROUTE` if channel name contains "archive", otherwise `NONE` or `UNKNOWN`.1581595. **Fetch SLA** via `/api/enterprise/sla/<enterprise_account_id>` → `monthly_export_credit_percent`.1601616. **Fetch enterprise account** for finance_owner and tier.1621637. **Naming conventions** (from response_requirements):164 - `channel_name`: lowercase-hyphen channel name from messages.165 - `evidence_folder`: `{client-lowercase-hyphen}-{YYYY-MM}-investigation` (e.g., `asteri-retail-2026-05-investigation`).166 - `report_title`: `{client-lowercase-hyphen}-export-failure-report`.1671688. **Share permissions**: Map from `permission_users_to_include`. Users matching finance_owner or account_owner typically get `view`. Order by the requirements list.1691709. **Response status**:171 - `NEEDS_FINANCE_REVIEW` when SLA credit > 0% is involved.172 - `NEEDS_ENGINEERING_REVIEW` when root cause is unclear or backfill incomplete.173 - `READY_TO_SEND` when all evidence is clear, backfill confirmed, no credit issues.174 - `UNDER_INVESTIGATION` when incident status in API is unresolved and data is insufficient.17517610. **root_cause_category**: Human-readable summary inferred from failure_code + message body (e.g., `STALE_CREDENTIAL` → "Stale Credential Rotation").177178## Task Type 4: Queue Quality Analysis (Pre-SLA Review)179180**Input**: CSV of ticket_ids with account_ids, service_type, queue_note.181**Key question**: Classify each ticket by resolution status, route team, key blocker, and diagnostic requirement.182183### Decision SOP184185Same initial flow as Task Type 1 (account → outage check → diagnostics → troubleshooting), but with a different answer schema focused on `key_blocker` and `route_team` rather than detailed issue flags.186187**Key differences from Task Type 1**:188- When account is not found: `FAILED`, `NONE`, `INVALID_ACCOUNT`.189- When auth has failed but account Active: `FAILED`, `NONE`, `AUTH_FAILED`.190- Route team is `NONE` when no escalation is needed (outage wait, invalid account, auth fail, auto-resolved).191- Queue summary includes counts per escalation team: TIER2_SUPPORT, FIELD_OPS, NETWORK_ENGINEERING, ACCOUNTS_PAYABLE.192193## Task Type 5: Mobile Data Recovery194195**Input**: JSON worklist with case_ids + customer_preferences map.196**Key question**: Select primary/secondary actions, refuel amount, charge, carrier update flag, and route.197198### Decision SOP199200Same device/line/bill inspection as Task Type 2, but focused on mobile data issues. Additional considerations:2012021. **Data refuel**: When `data_used_gb > plan.data_limit_gb`:203 - Read `customer_preferences[case_id].accepted_refuel_gb` for the refuel amount.204 - `charge_amount_usd = accepted_refuel_gb × plan.data_refueling_price_per_gb` (rounded to 2 decimals).205 - `data_refuel_gb`: the accepted_refuel_gb value (1 decimal).206 - If `does_not_want_plan_change: true`, do not suggest a plan change; just refuel.2072082. **Carrier updates**: When line-side settings need carrier action (e.g., `ENABLE_LINE_ROAMING`), `carrier_update_required: true`, route=`CARRIER_UPDATE`.2092103. **Device setting fixes**: TOGGLE_MOBILE_DATA, TOGGLE_DATA_SAVER, SET_NETWORK_MODE, DISCONNECT_VPN → route=`DEVICE_SETTING_FIX`.2112124. **Worklist summary**: Count per final_route plus `total_estimated_customer_charge_usd` (sum of all charge_amount_usd).213214## Common Pitfalls2152161. **Not checking outages first**: Always query `/api/outages?service_area=<area>` BEFORE concluding on diagnostics. An active outage overrides all other analysis — the ticket becomes `PENDING_ACTION` / `OUTAGE_WAIT`.2172182. **Account status before diagnostics**: A Suspended or auth-failed account makes diagnostics irrelevant. Check account status first.2192203. **Invalid account IDs in payload**: Account IDs like `BAD-XXXX` return `{"error": "not_found"}` — don't assume the account exists just because the ticket CSV lists it.2212224. **Roaming mismatch**: Distinguish device-side (`phone_roaming_enabled`) from line-side (`roaming_enabled`). Device toggle → `TOGGLE_ROAMING`; line toggle → `ENABLE_LINE_ROAMING` (carrier action).2232245. **MMS permissions**: MMS requires both `sms` and `storage` device permissions. Check `messaging_permissions` object, not just `can_send_mms`.2252266. **Export backfill vs failure count**: `backfill_days` = number of SUCCEEDED backfill runs, NOT the number of failed days. A single successful run after 3 failures = 1 backfill day.2272287. **Plan data limits**: Always fetch the plan to get `data_limit_gb` — don't assume a fixed limit. Compare `line.data_used_gb` to `plan.data_limit_gb`.2292308. **Answer template order**: Preserve payload order for ticket/case arrays. Sort by ascending case_id or payload order as specified in the template comments.2312329. **Numeric precision**: charge_amount_usd always 2 decimal places; data_refuel_gb always 1 decimal place.23323410. **SLA credits trigger finance review**: Any non-zero SLA credit percent means `response_status` should be `NEEDS_FINANCE_REVIEW`.235236## Field Value Quick Reference237238### Ticket resolutions239- `RESOLVED`: Auto-TS fixed the issue (metrics improved to acceptable levels).240- `PENDING_ACTION`: Waiting on outage resolution OR customer payment/action.241- `ESCALATED`: Needs another team (FIELD_OPS, NETWORK_ENGINEERING, TIER2_SUPPORT).242- `FAILED`: Unresolvable via support (INVALID_ACCOUNT, AUTH_FAILED).243244### Escalation teams245- `NONE`: No team needed (auto-resolved, outage wait, or unfixable).246- `TIER2_SUPPORT`: Configuration/provisioning issues beyond auto-TS.247- `FIELD_OPS`: Physical damage (fiber, line faults).248- `NETWORK_ENGINEERING`: Capacity/backbone issues.249- `ACCOUNTS_PAYABLE`: Billing/suspension issues.250251### Mobile final routes252- `SELF_SERVICE`: User can fix on device.253- `BILLING_RECOVERY`: Overdue bill payment needed.254- `CARRIER_UPDATE`: Line-side change needed.255- `HUMAN_TRANSFER`: No self-service fix possible.256- `DATA_RECOVERY`: Data refuel/plan change.257- `DEVICE_SETTING_FIX`: Toggle or setting change on device.