debug-ziti-desktop-edge-win -- Claude Skill
A Claude Code skill that analyzes a ZDEW feedback zip and produces a structured diagnostic report.
Self-contained: all commands are inline in the markdown. Nothing to install, no helper scripts to run.
SKILL.md is the spine that runs on every ticket -- locate the bundle, extract it, date the machine, check log
coverage, verify prior asks, build the service lifecycle. It ends in a dispatch table that names which
references/ file to read for the ticket in hand. Those files hold the deep procedure per area and are loaded
only when their trigger fires, so a straightforward bundle never pays for the crash-dump or fleet-comparison
material.
| File | Read when |
|---|---|
references/ziti-dump.md |
the capture has a *.ziti file (almost always) |
references/errors-and-warnings.md |
characterizing what the logs complain about (almost always) |
references/crash-dumps.md |
a .dmp exists, or the lifecycle shows an ungraceful exit |
references/config-identity-restore.md |
settings or identities went missing, typically after a Windows update |
references/tun-dns-routes.md |
DNS, IP range, or a suspected conflict with another VPN/ZTNA client |
references/fleet-comparison.md |
the ticket carries more than one capture |
references/report-template.md |
at write-up |
Setup
Copy the whole directory -- the skill reads references/ at run time.
mkdir -p ~/.claude/skills/debug-ziti-desktop-edge-win
cp -r SKILL.md references ~/.claude/skills/debug-ziti-desktop-edge-win/
Usage
/debug ziti-desktop-edge-win [ticket number or zip path]
Give it a ticket number and it fetches the bundle from whatever support-desk integration is available in the session, listing the attachments first so you pick the right one. Give it a zip path, or leave a zip in the working directory, and it uses that instead.
What it does
- Locates the bundle -- invocation arg, working directory, or ticket attachment. Reads the ticket comments, including internal ones, to find the hypothesis under test.
- Dates the machine -- OS build, boot time, and
Original Install Date, which an in-place Windows upgrade resets and which therefore dates the upgrade. - Checks log coverage -- ZDEW prunes its own logs on startup, so bundles collected days later often do not contain the incident. This gates everything downstream.
- Verifies prior asks -- whether the restart or trace-logging that support requested actually happened.
- Service lifecycle -- starts, stops, reboots, monitor actions, aliveness peaks. An orphan
service beginswith no matchingservice endsis the crash marker, once reboots are subtracted via the monitor'sOnShutdown. - Crash / stall dumps -- which of the two writers produced each dump, mtime converted from machine-local
to UTC, correlation against the identity certificate's
Not Before, and exception record plus registers read straight out of the dump without a debugger, plus the WinDbg steps for a full symbolized stack. - Config and identity handling -- the
Windows.old/Windows.~BTrestore path, for settings-loss and identity-loss tickets. - Tun adapter, DNS range, routes -- configured vs default range, and which adapter actually owns each contested CGNAT route.
- Errors and warnings -- bucketed by message shape, split into network / service-dial / routing-NRPT, with resume-from-sleep and midnight-OIDC baselines so normal churn isn't escalated.
.zitidump -- controllers, channels, connections, API session, per identity.
What it handles
- Single feedback zip -- standard capture from one machine
- Aggregated zip -- a zip of timestamped feedback zips; each inner capture is extracted and analyzed separately
- Fleet ticket -- many separate bundles on one ticket, one per machine, named after the host. All of them
are downloaded, then compared against each other: find the quiet machine and diff it against a loud one,
bucket signature errors per machine per day to separate infrastructure from local, and measure inbound
reachability from
on_hosted_client_connectcounts
Handling the data
A feedback bundle is confidential customer material. Identity .json files contain enrollment tokens, private
keys, and client certificates; .ziti dumps contain session certificates and tokens; the system and UI logs
contain usernames, hostnames, domains, internal IPs, and internal service names. The skill keeps bundles and
the extracted tree out of any repo, in a durable per-ticket archive under C:\temp\support\nfsupport\ (or
C:\temp\support\ if the former does not exist) whose full path it reports before it starts. It quotes the
minimum log text needed as evidence, and never puts identity file contents or tokens in a report.
Design notes
The skill is opinionated about a few failure modes that produced wrong answers in practice:
- Absence of a log line is not evidence until log coverage, log level, and rolled files are all checked.
WARNis scanned as well asERROR-- some of the highest-volume real defects never reachERROR.- Routes in
100.64.0.0/10are attributed by interface, because Zscaler, Netskope, GlobalProtect and dock NICs all live in CGNAT space and get mistaken for ZDE. uptime[Ns]in a.zitidump is per-identity context uptime, not process uptime.ziti-tunneler.logduplicates the current day's rolled file, so a naive glob double-counts every event from the collection day and invents phantom restarts.System Boot Timedrifts under Fast Startup and has been observed after a monitor shutdown event. Reboots are identified fromOnShutdown, not from boot time.err=-Nfromon_tcp_client_err()is an lwIPerr_t, not a libuv errno.-13isERR_ABRTand is high-volume noise that has already misdirected one analysis.- A list of known misleading strings, including
1168(The operation completed successfully.-- a failure whose message text says the opposite. - One dump is never generalized to the rest; exception records are compared across dumps before any shared cause is claimed.
Output
One report per capture, written to the working/repo directory (not into the extracted log tree), separating observation from inference and closing with a numbered "what to act on" list.