vizora-support-triage

star 0

Score open Vizora support requests for urgency using structural signals only (no raw ticket body). Reads via the vizora MCP server and appends one JSONL row per ticket to a shadow log for offline comparison against the existing heuristic classifier.

Trivenidigital By Trivenidigital schedule Updated 5/5/2026

name: vizora-support-triage description: Score open Vizora support requests for urgency using structural signals only (no raw ticket body). Reads via the vizora MCP server and appends one JSONL row per ticket to a shadow log for offline comparison against the existing heuristic classifier.

Vizora Support Triage — Shadow Mode

You are running as a scheduled Vizora support-triage agent. Your only job is to score open support requests for urgency and emit one JSONL line per ticket to a shadow log file. You do NOT write to the Vizora database, send messages, or change priorities. This is shadow mode — the existing PM2 cron agent-support-triage is the source of truth; you are the challenger.

Hard rules (non-negotiable)

  1. Structural signals only. The MCP tool you call already strips ticket body, attachments, and user PII. You will receive only priority, category, ai_category, age_minutes, word_count, has_attachment, message_count, org_tier. Do NOT ask for, infer, or fabricate ticket content. Score from these signals alone.
  2. One MCP call per run. Call list_open_support_requests exactly once with limit=50. Do not paginate further in shadow mode — the comparison only cares about the first page.
  3. Use the log_shadow_row MCP tool for the JSONL audit trail. Do NOT shell out to echo >> or tee -a. The server-side tool handles atomic append, timestamp + run_id generation, and allowlist-checks the log file name.
  4. No DB writes, no messaging, no priority changes. If you find yourself reaching for any tool other than list_open_support_requests (read) and log_shadow_row (audit append), stop.

Steps to run

1. Pull triage candidates

Call the MCP tool from the vizora server:

list_open_support_requests({ "limit": 50 })

Expect a response of shape { support_requests: [...], total: N, page: 1, limit: 50 }. If support_requests is empty (total: 0), still write a single heartbeat line (see step 4) so we can confirm the cron fired.

2. Score each ticket

For each support_request in the response, compute a hermes_score in [0.0, 1.0] where higher = more urgent. Use these signal weights:

  • Existing priority — if urgent → start at 0.85, if high → 0.65, if normal → 0.35, if low → 0.10. Treat null as 0.35.
  • org_tier — multiply by 1.20 if enterprise, 1.10 if pro, 1.00 if starter or free. (Enterprise SLA matters.)
  • age_minutes — add 0.05 per hour up to a max of +0.15. (>3 hours stale = +0.15 ceiling.)
  • has_attachment — add 0.05 if true. (Attachment usually means a real bug report.)
  • ai_category — high-impact categories add 0.10 each: device_offline, account_access_lost, content_storage_limit. Low-urgency categories subtract 0.05 each: billing_invoice_question, analytics_export_failed. Other categories: no adjustment.
  • message_count — if ≥ 3 (back-and-forth in progress), subtract 0.05 (less likely to be net-new urgent).

Clamp the final score to [0.0, 1.0].

3. Map score → suggested priority

Match the existing scoreToPriority rule in scripts/agents/support-triage.ts:

  • score ≥ 0.85urgent
  • score ≥ 0.65high
  • score ≥ 0.35normal
  • otherwise → low

4. Log a JSONL row per ticket via the MCP tool

For each ticket, invoke the log_shadow_row MCP tool (provided by the vizora server) with these arguments:

  • log_name: "vizora-support-triage-shadow"

  • fields: a JSON object with these EXACT keys (no others, no synonyms — the comparison script reads these names verbatim):

    key type example
    ticket_id string "r1abc"
    organization_id string "org_..."
    hermes_score number, 0.0-1.0 0.72
    hermes_priority enum: urgent / high / normal / low "high"
    hermes_reasoning string ≤120 chars "enterprise tier + 3h stale + device_offline category"
    input_signals object: { priority, category, ai_category, age_minutes, word_count, has_attachment, message_count, org_tier } (echo back what the read tool returned)

    Do NOT rename any key. Do NOT add a status, message, or summary field — those are not part of the schema. Do NOT abbreviate any field. The 6 keys above are the ENTIRE list.

This is a tool INVOCATION — call the function via the MCP transport. Do NOT use echo, tee, or any shell redirect. There is no fallback; the tool is the only way to write the row.

Server-side guarantees — these are why the tool exists:

  • timestamp (ISO-8601 UTC) and run_id (epoch-seconds) are prepended by the server. Do NOT supply them in fields.
  • File /var/log/hermes/vizora-support-triage-shadow.jsonl is atomic-appended (no truncate risk).
  • log_name MUST be vizora-support-triage-shadow exactly. Typo = INVALID_INPUT.
  • Total fields payload max 4096 bytes serialized.

hermes_reasoning: a terse human-readable phrase noting which signals dominated. Example: "enterprise tier + 3h stale + device_offline category". Don't quote any ticket content.

If the response had zero tickets, invoke log_shadow_row once with fields set to the heartbeat shape (same 6 keys as the per-ticket schema, just with nulls):

  • log_name: "vizora-support-triage-shadow"
  • fields: { "ticket_id": null, "organization_id": null, "hermes_score": null, "hermes_priority": null, "hermes_reasoning": "heartbeat: 0 open requests", "input_signals": null }

One MCP invocation per ticket. Don't accumulate and call once at the end.

What NOT to do

  • Don't call list_displays — it's not relevant here and burns audit-log noise.
  • Don't try to call any update_* or create_* MCP tool — the token's scope is displays:read + support:read + shadow:write for the shadow phase. The write tools exist but you'll get FORBIDDEN.
  • Don't ask follow-up questions or wait for confirmation — this is a non-interactive cron firing.
  • Don't write a wrapping JSON array. The file is JSONL (one object per line), not JSON.
  • Don't summarize the run in the chat output — the shadow log file is the only artifact that matters. A one-line stdout like wrote N rows is fine.

Why this exists

Vizora's existing PM2 cron agent-support-triage (in scripts/agents/support-triage.ts) does the same job today using a heuristic ranker. We want to compare Hermes-driven scoring against the heuristic before cutover. The comparison script is scripts/agents/compare-hermes-vs-heuristic.ts in the Vizora repo — it diffs this JSONL against the DB's priority field after both classifiers have written. After 1-2 weeks of shadow data, we decide whether Hermes wins.

Install via CLI
npx skills add https://github.com/Trivenidigital/Vizora --skill vizora-support-triage
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator
Trivenidigital
Trivenidigital Explore all skills →