Gossipper analyze
Skill VoicenterTeam/gossipper-skills/skills/gossipper-analyze
Interpret Gossipper output artifacts (summary JSON, trace CSVs, call records JSONL, OTLP events) and produce a structured findings report. Use whenever the user wants to classify failures from a Gossipper run, evaluate latency or media quality verdicts, decide whether a run passed health thresholds, propose threshold values for the next run, convert RTCP jitter from RTP timestamp units to milliseconds, surface Call-IDs and time windows for HOMER/qryn correlation, interpret exit code 2, or read a "Run report" handed over from gossipper-run.From its SKILL.md
npx -y skills add VoicenterTeam/gossipper-skills --skill gossipper-analyzeAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
18.3 KB, ~4.7k tokens by cl100k_base, as published. Nobody here has run it
gossipper-analyze — Output Interpretation
Interpret Gossipper outputs and produce structured findings. Pinned to Gossipper 0.1.60-rtcpmuxpatch2 (sipcapture/gossipper on main, audited 2026-05-18).
When to use this skill
- Read a "Run report" from gossipper-run and start an analysis.
- Classify failures from per-call records (
success: false+errorstring) and summary counters; surface dominant failure cause. - Compute latency verdicts (
invite_rtt,call_length, customrtdtimers). - Compute media-quality verdicts (RTCP loss, jitter, per-call RTP floor).
- Convert RTCP jitter fields (
media.RTCPMaxJitter/RTCPMinJitter/ etc., in RTP timestamp units) to ms. - Decide whether a run passed health thresholds (or apply them post-hoc if
-health_*wasn't set). - Propose threshold values for the next run, by intent.
- Surface Call-IDs, time windows,
hep_capture_id,self_tagfor downstream HOMER/qryn correlation. - Interpret exit code 2 and what to do about it.
When NOT to use this skill
| Task | Owner |
|---|---|
| Invoke gossipper, pick flags, deploy | gossipper-run |
| Write or modify scenario XML | gossipper-build |
| Query HOMER/qryn ClickHouse directly | separate query layer (out of scope here) |
| Decide whether to escalate findings to humans / autonomous controllers | caller of this skill |
This skill reads files and produces verdicts. It does not run, write, or query.
Inputs from gossipper-run
After every run, gossipper-run surfaces a structured "Run report" block in chat. Parse it — the file paths and correlation IDs come from there.
Run report
----------
Invocation: <command line or profile path + alias>
Started / ended: <ISO 8601> / <ISO 8601>
Exit code: <0 | 1 | 2>
Outputs produced:
summary_json: <path>
trace_stat: <path or omitted>
call_records_jsonl: <path or omitted>
message_file: <path or omitted>
error_file: <path or omitted>
wav_dir: <path or omitted>
Correlation identifiers:
hep_capture_id: <int or omitted>
self_tag: <id or omitted>
hep_addr: <host:port or omitted>
otel_endpoint: <host:port or omitted>
Notes: <operational context>
Two things to check before opening any file:
-
Exit code sets expectations.
0→ summary JSON exists, clean run.1→ summary JSON may be missing. Read*_err.logfirst.2→ summary JSON exists withhealth+findingspopulated.
-
Required channels. If anything you need is missing, do not fudge — state what's needed and ask the user to request those flags on the next gossipper-run invocation:
-summary_json <path>— always required.-trace_stat -fd <n>— required for time-series drill-down.-call_records_jsonl <path>— required for per-call diagnostics.-trace_err -error_file <path>— required whentransport_error/parse_errorshows up.
This skill does not control run's invocation. It tells the user what to ask for; run wires it.
Analysis workflow
- Exit code first. 0 / 1 / 2 sets expectations.
- Summary JSON next. Read in order (field paths verified against
gossipper_summary_v1, Gossipper 0.1.60-rtcpmuxpatch2):total_calls/success_ratio→ basic verdict.timeouts+retransmits(top-level aggregate counters) → high-level signal. The summary does NOT carry a per-classfailures.{timeout|unexpected_sip|...}breakdown — that comes from parsing per-call records.invite_rtt+call_length(each is an object withaverage/min/max/stddev/buckets) + any customrtdtimer keys → signaling timing. Latency values are in nanoseconds. Divide by 1_000_000 for ms.media.*→ only if scenario uses RTP. Field names are snake_case in the summary (rtp_packets_sent,rtcp_max_fraction_lost,rtcp_max_jitter_tsif present). Convert any RTP-TS jitter to ms via codec clock. (See "Codec → ms" section.)findings[](always present as array of strings if summary is) andhealth.passed/health.findings[]→ final verdict if-health_*thresholds were set at runtime.
- Drill into trace CSVs if summary numbers raise questions:
*_rtt.logfor per-call latency distribution / percentiles.*_stats.logfor time-series — when did failures spike?*_error_codes.logfor SIP-status breakdown.
- Per-call records JSONL for individual failed-call diagnostics — find failed calls by
success == falseand pull theircall_id. Each failed call has anerrorfree-text string (e.g."sip recv: timed out after 27.997s ..."); classify by regex if needed. Field list is enumerated inreferences/output-schema-reference.md; ifschema_versiondiffers fromgossipper_call_record_v1, re-inventory via the drift-detection recipe in that doc. - Surface correlation pointers for downstream HOMER/qryn lookup. Do not attempt the query.
- Read
*_msg.log/*_err.logonly when steps 1–5 don't explain it — last-resort context.
Full output-channel matrix and field references → references/output-schema-reference.md.
Failure classification
The 0.1.60-rtcpmuxpatch2 binary does NOT emit a structured failure-class enum. Per-call records carry success: bool plus a free-text error string on failures. To classify, parse the error field with the regex table below — these classes are derived, not binary-native.
| Class | Match on error (case-insensitive substring or regex) | Means |
|---|---|---|
timeout | sip recv: timed out, recv timeout, timed out after | Expected recv didn't arrive within -recv_timeout_ms (or -recv_bye_timeout_ms for BYE) |
unexpected_sip | unexpected, did not match, no matching recv | SIP message didn't match current recv AND _unexp.main fallback didn't recover |
transport_error | connection refused, connection reset, i/o timeout (transport context), tls handshake | Socket-level failure |
parse_error | parse error, malformed, invalid sip | SIP message malformed beyond parser tolerance |
scenario_error | scenario, divide by zero, missing variable, bad xml | Action failed at runtime |
cancelled | cancelled, canceled, context deadline exceeded (run-level) | Run terminated externally while call was active |
First analysis question: count success == false records per derived class. Which class dominates?
Aggregate signal at summary level: only timeouts is broken out as a top-level counter; everything else (failed_calls, success_ratio) is undifferentiated. Lean on per-call parsing for breakdown.
Triage workflow per class → references/patterns.md.
Codec → ms conversion (the jitter gotcha)
Per-call record fields (PascalCase): media.RTCPMaxJitter, RTCPMinJitter, RTCPJitterSum (with RTCPJitterSamples for averaging), and RTPRecvInterarrivalJitterPeak.
Summary JSON fields (snake_case, when present): media.rtcp_max_jitter_ts, rtcp_avg_jitter_ts, rtcp_min_jitter_ts, rtp_recv_interarrival_jitter_peak_ts.
Both surfaces report jitter in RTP timestamp units, not milliseconds. Conversion depends on the negotiated codec's sample rate.
| Codec(s) | Clock | Divide by |
|---|---|---|
| PCMU / PCMA / G722 / iLBC | 8 kHz | 8 |
| OPUS | 48 kHz | 48 |
| H264 | 90 kHz | 90 |
Always report jitter in ms. Always state the codec assumption.
Codec inference rules:
- Built-in scenarios (
-sn uac,-sn uas): assume PCMU at 8000 Hz, 20 ms ptime. Recordcodec_assumedin the findings report'sconcerns[](see "Concerns schema" section below). Do not prompt the user. - Custom scenarios (
-sf <file>): if the SDP / scenario doesn't declare a codec, ask the user. Built-in defaults do NOT apply. - Override: user may supply
codec=<g711a|g722|opus|...>as an analyze-time hint, or annotate the run-profile JSON with acodec_assumptionfield. Override always wins; record the user's value in findingsinputs.codec_assumption.
Health threshold authoring
When the user asks for threshold values for -health_* on the next run, propose by intent. The user (or caller) confirms; gossipper-run wires them. This skill never sets flags itself.
Sample threshold sets per run intent → references/patterns.md (SOC monitor / soak / regression / smoke).
-health_* flag list:
| Flag | Compared against | Pass condition |
|---|---|---|
-health_min_success_ratio <0..1> | summary success_ratio | >= threshold |
-health_max_failed_calls <n> | summary failed_calls | < threshold (0 = any failure fails) |
-health_max_timeouts <n> | summary timeouts (top-level counter) | <= threshold |
-health_max_rtcp_fraction_lost <0..1> | summary media.rtcp_max_fraction_lost (when present) | <= threshold |
-health_max_rtcp_jitter_ts <int> | summary media.rtcp_max_jitter_ts (when present); per-call media.RTCPMaxJitter | <= threshold (RTP TS units!) |
-health_min_rtp_packets_recv <n> | summary media.rtp_packets_received | >= threshold |
-health_min_rtp_packets_recv_per_call <n> | computed across per-call records' media.RTPPacketsReceived (min) | >= threshold |
Note — -health_max_rtcp_jitter_ts takes RTP timestamp units, not ms. When proposing it, multiply your ms target by the codec sample-rate divisor (e.g. 30 ms × 8 = 240 for PCMU). State the conversion in the proposal.
If -health_* was NOT set on the run, apply thresholds post-hoc against raw counters — same logic, in the findings report.
Exit code interpretation
| Exit | Means | What to do |
|---|---|---|
0 | Clean run, no health breach (or -health_* not set) | Read summary JSON. Check no false-positive successes — cancelled mid-run shouldn't count as benign. |
1 | Engine / parse / transport / scenario error before finalization | Summary JSON may be missing. Read *_err.log first. Hand back to build (XML problem) or run (flag/transport problem). |
2 | Health threshold breach | Summary JSON has health + findings. Lead with which dimension breached and by how much. |
Always-remember gotchas
- RTCP jitter fields are RTP timestamp units, not ms. Convert using the codec clock. Always declare the codec assumption. Field names: per-call PascalCase (
media.RTCPMaxJitteretc.); summary snake_case with_tssuffix (media.rtcp_max_jitter_tsetc.). dropped_logs > 0in OTLPengine.stoppedevents signals OTLP buffer overflow; treat OTLP stream as incomplete. The summary JSON does NOT carry an equivalentengine.stopped.dropped_logsfield directly — this is an OTLP-only signal. Check the OTLP collector side, not the summary.cancelledis timing-dependent. End-of-soak SIGINT or-timeout_globalproduces benign cancellations. Mid-run cancellation in a per-callerrorstring is a real failure. Inspect timestamps before concluding.unexpected_sipfollowed by_unexp.mainrecovery may still classify assuccess. The fallback exists to recover. Don't flag every_unexp.mainjump as a failure. (Per-call records that recovered will havesuccess: true.)- No packet-level RTP/RTCP in HEP. For per-packet analysis (loss bursts, codec-level issues), the user needs local PCAP via heplify on the gossipper host — not the HEP mirror. Tell them.
gossipper_call_record_v1field list is enumerated inreferences/output-schema-reference.md. Be defensive about field presence — failure-mode records omit some media subfield meaningful values (they're present but zeroed). Ifschema_versiondiffers fromgossipper_call_record_v1, follow the drift-detection recipe in the schema reference.- TLS handshake failures show in
errorstrings containing transport-level wording (e.g.tls handshake,connection refused). Look in*_err.logand per-callerror, not inauthevents. Failures are NOT pre-classified — derive class from the error text. - Summary JSON exists only after clean shutdown. SIGKILL → no summary. SIGINT → drain + summary write. If summary is missing on exit 1, that's why.
max_failed_calls: 0means "any failure fails health" — strict pass/fail gate, not "unlimited failures allowed."- Built-in
-sn uac/uasscenarios don't emit namedrtdtimers by default — onlyinvite_rttandcall_length. Custom timers require custom XML. - Summary latency values are in nanoseconds.
average_call_latency,average_invite_rtt, andcount.average/min/max/last/stddevinsideinvite_rtt/call_lengthobjects are ns — divide by 1_000_000 for ms. Always disclose units in the findings report.
Going deeper
Read on demand:
references/output-schema-reference.md— full schema lookup: output channel matrix,gossipper_summary_v1field reference (top-level +latencies+counters+media+health+findings),gossipper_call_record_v1known shape + inventory recipe, three contracted CSV headers verbatim, three non-contracted CSVs, OTLPKindenum with attrs, HEP3 mirror semantics, live API surfaces.references/patterns.md— how-to-act: per-class failure triage, codec → ms conversion details, health threshold authoring by run intent (SOC / soak / regression / smoke) with sample sets, correlation strategy (Call-ID selection + time-window inference), findings-report filling notes,jq/awkrecipes for common extractions, data-quality flag handling, rerun-vs-escalate decision patterns.
Verdict vocabulary
Verdict: in the findings report below is one of three values:
| Verdict | Meaning |
|---|---|
pass | Exit code 0 AND no post-hoc threshold breach. The run is good. |
breach | Exit code 2 (a -health_* threshold was set and breached at runtime) OR exit code 0 with a post-hoc threshold violation surfaced during analysis. |
hard_error | Exit code 1 — engine/parse/transport/scenario failure. Summary JSON may be missing. |
Soft signals (data-quality, codec assumptions, single-stat outliers) do not change the verdict — they go in the concerns[] array. See "Concerns schema" section below.
Findings report (handoff)
After analysis, surface this structured block in chat. Symmetric with gossipper-run's "Run report" — chat content, not a file artifact. The caller (human or autonomous controller) acts on it.
Findings report
---------------
Run identifier: <self_tag / hep_capture_id>
Verdict: pass | breach | hard_error
Inputs:
codec_assumption: <e.g. PCMU/8000 (assumed for built-in scenario)>
Failure breakdown (derived from per-call error parsing):
timeout: <n> unexpected_sip: <n> transport_error: <n>
parse_error: <n> scenario_error: <n> cancelled: <n>
(unclassified: <n>)
Latency (all values in ms, converted from ns):
invite_rtt: avg=<>ms max=<>ms
call_length: avg=<>ms
custom_rtds: <name>=avg=<>ms ...
Media (if applicable; codec: <>):
rtcp_max_fraction_lost: <0..1>
rtcp_max_jitter_ms: <> (converted from <> RTP TS units)
per_call_min_rtp_packets: <>
Health (if -health_* was set, or applied post-hoc):
passed: <bool>
breached: <thresholds with actual vs target>
Correlation pointers (for HOMER/qryn follow-up):
hep_capture_id: <int>
self_tag: <id>
time_window: <start ISO 8601> .. <end ISO 8601>
key_call_ids: <failed-call IDs, capped at N>
Threshold proposals for next run (if any):
-health_min_success_ratio <val>
-health_max_timeouts <val>
...
Concerns (see "Concerns schema" section; may be empty):
- code: <code> severity: <info|notice> message: <one-line>
Recommended next step:
<rerun with X via gossipper-run | scenario change Y via gossipper-build |
escalate: production-side HOMER/qryn correlation needed>
Do NOT paste raw summary JSON alongside this block — the report is the synthesis, not a wrapper. Paths live in the Run report; the caller re-opens them if needed.
Concerns schema
Verdict is pass | breach | hard_error. Concerns carry soft signal that doesn't change the verdict but a reviewer should see. Always emit as a top-level concerns[] array in the structured findings (alongside the chat-format report above); empty array is fine. The chat-format report's "Concerns" section enumerates them one bullet per entry.
Shape (structured findings)
{
"verdict": "pass",
"inputs": {
"self_tag": "...",
"codec_assumption": "PCMU/8000"
},
"concerns": [
{
"code": "jitter_variance_high",
"severity": "info",
"message": "Jitter mean 8ms (within 30ms budget) but stddev 12ms — high variance",
"metric": { "name": "jitter_stddev_ms", "value": 12, "threshold": null }
}
]
}
severity is one of info | notice. Anything that should fail a run goes into verdict: breach, not concerns[].
Trigger codes (initial set)
| Code | Trigger condition | Severity | Example metric |
|---|---|---|---|
jitter_variance_high | Jitter mean within budget, but stddev > 50% of mean | info | jitter_stddev_ms |
retransmit_present | Summary retransmits > 0, even if calls completed successfully | info | retransmits |
codec_assumed | Codec inferred via the PCMU default rule for -sn uac/uas runs | info | n/a |
partial_data | Summary JSON missing expected fields (findings[] empty, summary missing entirely on exit 1, etc.) | notice | depends |
unclassified_failures | Per-call records contain success: false with error strings not matching any class regex | notice | unclassified_count |
Add new codes only when a recurring case warrants one — don't proliferate single-use codes.
When to emit which
pass+ non-emptyconcerns[]→ "passed, but reviewer should see X." Common case.breach+concerns[]→ "failed on threshold Y, also worth noting Z." Concerns are additive, not redundant with breach detail.hard_error+concerns[]→ rare but valid; e.g. "summary missing — verdict provisional based on exit code alone."
What ships with it: 6 files
38.5 KB alongside SKILL.md
examples/
references/
- output-schema-reference.md17.9 KB
- patterns.md16.5 KB
Gives 0 of the 12 instructions most research analysis skills give in ~4.7k tokens
Counted across 1,063 of the 1,754 authors here whose files we hold, read 2026-08-07
- Generate a markdown reportin 32 of 1063, across 23 files
- Cite each claim's sourcein 30 of 1063, across 15 files
- Define the ideal customer profilein 20 of 1063, across 2 files
- Search for companies matching the criteriain 20 of 1063, across 2 files
- Assign a fit score from one to tenin 20 of 1063, across 2 files
- Analyze the codebase to understand the productin 19 of 1063, across 1 file
- Ask clarifying questions about the value propositionin 19 of 1063, across 1 file
- Look for signals of immediate needin 19 of 1063, across 1 file
- Identify the target decision maker rolein 19 of 1063, across 1 file
- Suggest a personalized contact strategyin 19 of 1063, across 1 file
- Provide conversation starters for outreachin 19 of 1063, across 1 file
- Format results in a scannable markdown templatein 19 of 1063, across 1 file
Said here and by no other author read
- parse the run report block for file paths
- check exit code before opening files
- read summary json for verdicts and counters
- divide latency values by 1000000 for milliseconds
- convert rtcp jitter from timestamp units to milliseconds
- declare the codec assumption used for jitter conversion
Grouped from the skills themselves: near-identical wordings counted once, and counted by distinct author, so one author publishing three of these counts once. Length counted with cl100k_base; the agent that loads this file may tokenize it differently.