Forward Skill
Skill: /forward
MCP Server: forward-mcp
Source: https://github.com/forwardnetworks/forward-mcp
Use When
Use this skill for Forward snapshot assurance, collection, and analysis:
- Discover Forward networks, snapshots, and devices
- Verify paths and reachability
- Discover and run NQE checks
- Review predefined checks, failed checks, and vulnerability analysis
- Compare NQE, snapshot, and config diffs
- Search configurations
- Analyze blast radius for a source location to destination IPv4 subnets
- Review hardware and OS lifecycle support
- Find missing devices inferred during collection
- Support lab or real-network collection workflows
Startup
- Start with
get_default_settings to see configured defaults.
- If no default network is set, use
list_networks with a small limit and ask
the user which network to use.
- Prefer explicit
network_id and snapshot_id values for repeatable results.
- Use bounded limits by default. Use
all_results only when the user needs the
complete dataset.
- In Forward SaaS, prefer
FORWARD_API_BASE_URL=https://fwd.app and set
FORWARD_INSTANCE_ID for local cache partitioning when multiple SaaS orgs or
accounts are used on the same NetClaw host.
Tool Routing
| User intent |
Preferred tools |
| "List Forward networks" |
list_networks |
| "Use this network by default" |
set_default_network |
| "Show collection sources" |
list_classic_devices, get_classic_device |
| "Add lab devices" |
upsert_classic_devices |
| "Show collector status" |
get_collector_status |
| "Start collection" |
start_collection_task, get_collector_task, then wait_for_latest_snapshot; use start_collection only for legacy flows |
| "Show snapshots" |
list_snapshots, get_latest_snapshot |
| "List devices" |
list_devices, get_device_basic_info |
| "Find missing collection neighbors" |
get_missing_devices |
| "Trace paths" |
search_paths_bulk, then search_paths for one-off traces |
| "Trace app-aware paths" |
list_l7_applications, then search_paths_bulk or search_paths with app_id, url, or domain |
| "Show blast radius" |
suggest_blast_radius_sources, then get_blast_radius |
| "Find NQE checks" |
search_nqe_queries, list_nqe_queries |
| "Run an NQE check" |
run_nqe_query_by_id; use start_nqe_query for long-running checks |
| "Write or run ad-hoc NQE" |
Prefer search_nqe_queries first; use run_nqe_query only when no built-in query fits and async NQE for long-running or large results |
| "Show predefined checks" |
list_predefined_checks |
| "Show failed checks or intent status" |
list_checks, then get_check |
| "Show vulnerabilities or CVE exposure" |
search_nqe_queries, then run_nqe_query_by_id with the /Security/CVEs/... query IDs |
| "Draw topology from Forward" |
get_snapshot_topology, then search NQE for CDP/LLDP and protocol-peer evidence when needed |
| "Summarize large results" |
get_nqe_result_summary, get_nqe_result_chunks, analyze_nqe_result_sql |
| "Search configs" |
search_configs |
| "Compare NQE or intent/check results" |
get_nqe_diff |
| "Summarize snapshot diffs" |
get_snapshot_diff_summary |
| "Show route, ACL, NAT, interface, check, or vulnerability diffs" |
get_snapshot_diff |
| "Compare snapshots/configs" |
get_config_diff |
| "Check hardware or OS support" |
get_device_hardware, get_hardware_support, get_os_support |
| "Show locations" |
list_locations, get_device_locations |
NQE Discovery Notes
Forward MCP owns the NQE catalog. Do not copy catalog contents into NetClaw.
For natural-language NQE requests:
- Prefer first-class tools when they match the intent, such as
get_device_basic_info, get_device_hardware, get_hardware_support, or
get_os_support.
- Otherwise use
search_nqe_queries with the user's intent.
- Use
list_nqe_queries only when the directory or query family is already
known.
- Preserve the returned
FQ_... query ID in the answer and execute it with
run_nqe_query_by_id.
- Keep limits bounded unless the user asks for complete data.
Use run_nqe_query for ad-hoc NQE source only after checking whether a
built-in query already answers the question and the expected result fits a
bounded synchronous call. For long-running or large queries, use
start_nqe_query, poll get_nqe_query_status, then fetch rows with
get_nqe_query_result. These execute raw NQE or query IDs through Forward's
native NQE APIs; they do not create or save a new query in the NQE Library. Keep
ad-hoc queries narrow, set limits by default, and explain when the result is
from custom source rather than a built-in Forward query. Use all_results: true
only when the user needs the complete table.
Constructing Ad-Hoc NQE
Prefer built-in query IDs when they fit. When a question needs raw NQE, build it
incrementally and execute it through Forward MCP:
- Start with a tiny selector such as
foreach d in network.devices select { Name: d.name }.
- Add one model surface at a time, then run
start_nqe_query, poll
get_nqe_query_status, and page with get_nqe_query_result.
- Keep filters inside NQE instead of post-processing large result sets.
- Use schema-native types and OneOf patterns. Enumerations can be compared as
NatType.LB; data-bearing OneOf values use when ... is.
Useful raw NQE patterns:
On-prem load balancer VIPs, DNAT-style rewrites, and backend targets:
foreach device in network.devices
foreach natEntry in device.natEntries
where natEntry.natType == NatType.LB
foreach rewrite in natEntry.rewrites
select {
LoadBalancer: device.name,
Vip: natEntry.headerMatches.ipv4Dst,
Ports: natEntry.headerMatches.tpDst,
Backends: rewrite.ipv4Dst,
BackendPorts: rewrite.tpDst
}
Other VIPs in the same subnet:
targetSubnet = ipSubnet("110.240.240.0/24");
foreach device in network.devices
foreach natEntry in device.natEntries
where natEntry.natType == NatType.LB
foreach vip in natEntry.headerMatches.ipv4Dst
where vip in targetSubnet
foreach rewrite in natEntry.rewrites
select {
LoadBalancer: device.name,
Vip: vip,
Ports: natEntry.headerMatches.tpDst,
Backends: rewrite.ipv4Dst
}
Cloud VPC load balancers:
foreach cloudAccount in network.cloudAccounts
foreach vpc in cloudAccount.vpcs
foreach loadBalancer in vpc.loadBalancers
foreach rule in loadBalancer.loadBalancerRules
foreach backend in rule.backends
let server = when backend is
server(backendServerData) -> backendServerData;
otherwise -> null : BackendServer
where isPresent(server)
select {
CloudAccount: cloudAccount.name,
Vpc: vpc.name,
LoadBalancer: loadBalancer.name,
FrontendIps: rule.frontendIps,
FrontendPorts: rule.frontendPorts,
BackendIps: server.backendIps,
BackendPorts: server.backendPorts
}
VIP route propagation:
targetVip = ipSubnet("110.240.240.240/32");
foreach device in network.devices
foreach vrf in device.networkInstances
where isPresent(vrf.afts.ipv4Unicast)
foreach route in vrf.afts.ipv4Unicast.ipEntries
where targetVip in route.prefix
where length(route.prefix) >= 24
foreach nextHop in route.nextHops
select {
Device: device.name,
Vrf: vrf.name,
Prefix: route.prefix,
OriginProtocol: nextHop.originProtocol,
NextHopType: nextHop.nextHopType,
NextHopIp: nextHop.ipAddress,
Interface: nextHop.interfaceName
}
For topology, start with get_snapshot_topology for native directed links.
Then search for both link evidence and protocol-peer evidence when needed.
CDP/LLDP can describe physical neighbors; peer queries such as BGP can describe
relationships Forward models beyond discovery protocols.
If search_nqe_queries or list_nqe_queries reports that the query index is
empty, do this only in a persistent OpenClaw session and only after user
confirmation:
- Run
hydrate_database with regenerate_embeddings: false.
- Run
refresh_query_index.
- Retry
search_nqe_queries or list_nqe_queries.
Safety Rules
Default to read-only Forward tools. Require explicit human confirmation before
tools that create, update, delete, clear, hydrate, rebuild, start/cancel
collection, or set persistent defaults. This includes collector/source,
credential, network, snapshot, location, entity/relation, observation, local
cache/index, and set_default_network operations. Creating new Forward
networks requires full org admin privileges; do not use create_network unless
the user explicitly confirms that role. Updating an existing Forward network
requires network admin privileges.
Never put Forward credentials in repository files. Use ~/.openclaw/.env.
For private CA deployments, use FORWARD_CA_CERT_PATH; do not disable TLS
verification.
Workflows
Diffs
- Use
get_snapshot_diff_summary first for a bounded overview.
- Use
get_snapshot_diff for focused route, ACL, NAT, interface, check,
file/config, inventory-query, routing-loop, or vulnerability diffs.
- Use
get_nqe_diff for arbitrary NQE and intent-style query diffs.
- Use
get_config_diff when the user specifically asks for config text drift.
Blast Radius
- Use
suggest_blast_radius_sources if the source name or location filter is
uncertain.
- Use
get_blast_radius with source_device for a device source, or source
when the prompt already supplies Forward LocationFilter JSON.
- Keep
dst_subnets, timeout_seconds, and paging_options bounded.
- Use blast radius for security/exposure questions; use NQE for tabular
snapshot facts and
search_paths_bulk for specific path traces.
Checks and CVEs
- Use
list_checks with statuses such as FAIL, WARN, or ERROR to
triage intent/check state for a snapshot.
- Use
get_check for the detailed rows behind a specific failed check.
- Use
list_predefined_checks when the user asks what built-in checks exist.
- Use NQE for CVE posture. Prefer
search_nqe_queries for natural-language
discovery, then run_nqe_query_by_id.
- Useful built-in CVE query paths include
/Security/CVEs/CVE violations by CVE, /Security/CVEs/CVE violations by device,
/Security/CVEs/CVE violation details by device, and
/Security/CVEs/Vendor CVE metadata.
- Use
get_nqe_diff for CVE query drift between snapshots. Use
get_snapshot_diff with diff_type: "vulnerabilities" for the Forward
vulnerability diff domain.
Collection and Lab Demo
- Treat collection setup and start/cancel actions as admin workflows.
- Use them only on lab/admin networks or after explicit user confirmation.
- Treat collector installation/onboarding as a separate prerequisite. Anyone
can install or onboard a collector, but a network admin must assign that
collector to the target network. The stable Linux collector download URL is
https://fwd.app/api/software/client?type=LINUX.
- Before starting collection, run
get_collector_status and
list_classic_devices.
- Prefer
start_collection_task, poll it with get_collector_task, then use
wait_for_latest_snapshot. Use start_collection only when task creation is
unavailable in the target deployment.
Topology Drawing
- Prefer Forward NQE evidence for collected topology questions: link queries
plus relevant protocol-peer queries.
- If the NQE result only shows management-plane neighbors or incomplete links in
a real or emulated network, use the originating topology source as the edge
source and Forward as the collected assurance source.
- Use the available lab backend, source-of-truth, inventory, or discovery tool
to identify device names, management IPs, physical links, and credentials
before Forward collection.
- Before
start_collection, confirm the assigned Forward collector can reach
the target management network. If not, the missing step is collector
installation, assignment, or routing.
- Render a normalized node/edge list with Draw.io, Markmap, or another diagram
skill. Never infer links from names or management IPs alone.
Result Discipline
- Summarize large tables before presenting them.
- Preserve network IDs, snapshot IDs, query IDs, and device names in the answer.
- When a path or NQE result is inconclusive, say what data was missing and which
next read-only Forward tool should be run.
- For config and NQE diffs, separate intended changes from unexpected changes.
- For snapshot diffs, start with counts/summary and drill into the changed
domain that matters.
1---
2name: forward
3description: Forward snapshot assurance, path search, app-aware path search, NQE, checks, vulnerabilities, diffs, configuration, lifecycle, collection, and topology workflows through the upstream forward-mcp server.
4version: 1.0.0
5license: Apache-2.0
6author: forward
7tags: [forward, assurance, nqe, paths, diffs, collection]
8mcp_servers: [forward-mcp]
9metadata:
10 openclaw:
11 requires:
12 bins:
13 - mcp-servers/forward-mcp/forward-mcp
14 env:
15 - FORWARD_API_BASE_URL
16 - FORWARD_API_KEY
17 - FORWARD_API_SECRET
18 - FORWARD_INSTANCE_ID
19 - FORWARD_DEFAULT_NETWORK_ID
20---
21
22# Forward Skill
23
24**Skill**: `/forward`
25**MCP Server**: `forward-mcp`
26**Source**: <https://github.com/forwardnetworks/forward-mcp>
27
28## Use When
29
30Use this skill for Forward snapshot assurance, collection, and analysis:
31
32- Discover Forward networks, snapshots, and devices
33- Verify paths and reachability
34- Discover and run NQE checks
35- Review predefined checks, failed checks, and vulnerability analysis
36- Compare NQE, snapshot, and config diffs
37- Search configurations
38- Analyze blast radius for a source location to destination IPv4 subnets
39- Review hardware and OS lifecycle support
40- Find missing devices inferred during collection
41- Support lab or real-network collection workflows
42
43## Startup
44
451. Start with `get_default_settings` to see configured defaults.
462. If no default network is set, use `list_networks` with a small limit and ask
47 the user which network to use.
483. Prefer explicit `network_id` and `snapshot_id` values for repeatable results.
494. Use bounded limits by default. Use `all_results` only when the user needs the
50 complete dataset.
515. In Forward SaaS, prefer `FORWARD_API_BASE_URL=https://fwd.app` and set
52 `FORWARD_INSTANCE_ID` for local cache partitioning when multiple SaaS orgs or
53 accounts are used on the same NetClaw host.
54
55## Tool Routing
56
57| User intent | Preferred tools |
58|-------------|-----------------|
59| "List Forward networks" | `list_networks` |
60| "Use this network by default" | `set_default_network` |
61| "Show collection sources" | `list_classic_devices`, `get_classic_device` |
62| "Add lab devices" | `upsert_classic_devices` |
63| "Show collector status" | `get_collector_status` |
64| "Start collection" | `start_collection_task`, `get_collector_task`, then `wait_for_latest_snapshot`; use `start_collection` only for legacy flows |
65| "Show snapshots" | `list_snapshots`, `get_latest_snapshot` |
66| "List devices" | `list_devices`, `get_device_basic_info` |
67| "Find missing collection neighbors" | `get_missing_devices` |
68| "Trace paths" | `search_paths_bulk`, then `search_paths` for one-off traces |
69| "Trace app-aware paths" | `list_l7_applications`, then `search_paths_bulk` or `search_paths` with `app_id`, `url`, or `domain` |
70| "Show blast radius" | `suggest_blast_radius_sources`, then `get_blast_radius` |
71| "Find NQE checks" | `search_nqe_queries`, `list_nqe_queries` |
72| "Run an NQE check" | `run_nqe_query_by_id`; use `start_nqe_query` for long-running checks |
73| "Write or run ad-hoc NQE" | Prefer `search_nqe_queries` first; use `run_nqe_query` only when no built-in query fits and async NQE for long-running or large results |
74| "Show predefined checks" | `list_predefined_checks` |
75| "Show failed checks or intent status" | `list_checks`, then `get_check` |
76| "Show vulnerabilities or CVE exposure" | `search_nqe_queries`, then `run_nqe_query_by_id` with the `/Security/CVEs/...` query IDs |
77| "Draw topology from Forward" | `get_snapshot_topology`, then search NQE for CDP/LLDP and protocol-peer evidence when needed |
78| "Summarize large results" | `get_nqe_result_summary`, `get_nqe_result_chunks`, `analyze_nqe_result_sql` |
79| "Search configs" | `search_configs` |
80| "Compare NQE or intent/check results" | `get_nqe_diff` |
81| "Summarize snapshot diffs" | `get_snapshot_diff_summary` |
82| "Show route, ACL, NAT, interface, check, or vulnerability diffs" | `get_snapshot_diff` |
83| "Compare snapshots/configs" | `get_config_diff` |
84| "Check hardware or OS support" | `get_device_hardware`, `get_hardware_support`, `get_os_support` |
85| "Show locations" | `list_locations`, `get_device_locations` |
86
87## NQE Discovery Notes
88
89Forward MCP owns the NQE catalog. Do not copy catalog contents into NetClaw.
90For natural-language NQE requests:
91
921. Prefer first-class tools when they match the intent, such as
93 `get_device_basic_info`, `get_device_hardware`, `get_hardware_support`, or
94 `get_os_support`.
952. Otherwise use `search_nqe_queries` with the user's intent.
963. Use `list_nqe_queries` only when the directory or query family is already
97 known.
984. Preserve the returned `FQ_...` query ID in the answer and execute it with
99 `run_nqe_query_by_id`.
1005. Keep limits bounded unless the user asks for complete data.
101
102Use `run_nqe_query` for ad-hoc NQE source only after checking whether a
103built-in query already answers the question and the expected result fits a
104bounded synchronous call. For long-running or large queries, use
105`start_nqe_query`, poll `get_nqe_query_status`, then fetch rows with
106`get_nqe_query_result`. These execute raw NQE or query IDs through Forward's
107native NQE APIs; they do not create or save a new query in the NQE Library. Keep
108ad-hoc queries narrow, set limits by default, and explain when the result is
109from custom source rather than a built-in Forward query. Use `all_results: true`
110only when the user needs the complete table.
111
112### Constructing Ad-Hoc NQE
113
114Prefer built-in query IDs when they fit. When a question needs raw NQE, build it
115incrementally and execute it through Forward MCP:
116
1171. Start with a tiny selector such as
118 `foreach d in network.devices select { Name: d.name }`.
1192. Add one model surface at a time, then run `start_nqe_query`, poll
120 `get_nqe_query_status`, and page with `get_nqe_query_result`.
1213. Keep filters inside NQE instead of post-processing large result sets.
1224. Use schema-native types and OneOf patterns. Enumerations can be compared as
123 `NatType.LB`; data-bearing OneOf values use `when ... is`.
124
125Useful raw NQE patterns:
126
127On-prem load balancer VIPs, DNAT-style rewrites, and backend targets:
128
129```nqe
130foreach device in network.devices
131foreach natEntry in device.natEntries
132where natEntry.natType == NatType.LB
133foreach rewrite in natEntry.rewrites
134select {
135 LoadBalancer: device.name,
136 Vip: natEntry.headerMatches.ipv4Dst,
137 Ports: natEntry.headerMatches.tpDst,
138 Backends: rewrite.ipv4Dst,
139 BackendPorts: rewrite.tpDst
140}
141```
142
143Other VIPs in the same subnet:
144
145```nqe
146targetSubnet = ipSubnet("110.240.240.0/24");
147foreach device in network.devices
148foreach natEntry in device.natEntries
149where natEntry.natType == NatType.LB
150foreach vip in natEntry.headerMatches.ipv4Dst
151where vip in targetSubnet
152foreach rewrite in natEntry.rewrites
153select {
154 LoadBalancer: device.name,
155 Vip: vip,
156 Ports: natEntry.headerMatches.tpDst,
157 Backends: rewrite.ipv4Dst
158}
159```
160
161Cloud VPC load balancers:
162
163```nqe
164foreach cloudAccount in network.cloudAccounts
165foreach vpc in cloudAccount.vpcs
166foreach loadBalancer in vpc.loadBalancers
167foreach rule in loadBalancer.loadBalancerRules
168foreach backend in rule.backends
169let server = when backend is
170 server(backendServerData) -> backendServerData;
171 otherwise -> null : BackendServer
172where isPresent(server)
173select {
174 CloudAccount: cloudAccount.name,
175 Vpc: vpc.name,
176 LoadBalancer: loadBalancer.name,
177 FrontendIps: rule.frontendIps,
178 FrontendPorts: rule.frontendPorts,
179 BackendIps: server.backendIps,
180 BackendPorts: server.backendPorts
181}
182```
183
184VIP route propagation:
185
186```nqe
187targetVip = ipSubnet("110.240.240.240/32");
188foreach device in network.devices
189foreach vrf in device.networkInstances
190where isPresent(vrf.afts.ipv4Unicast)
191foreach route in vrf.afts.ipv4Unicast.ipEntries
192where targetVip in route.prefix
193where length(route.prefix) >= 24
194foreach nextHop in route.nextHops
195select {
196 Device: device.name,
197 Vrf: vrf.name,
198 Prefix: route.prefix,
199 OriginProtocol: nextHop.originProtocol,
200 NextHopType: nextHop.nextHopType,
201 NextHopIp: nextHop.ipAddress,
202 Interface: nextHop.interfaceName
203}
204```
205
206For topology, start with `get_snapshot_topology` for native directed links.
207Then search for both link evidence and protocol-peer evidence when needed.
208CDP/LLDP can describe physical neighbors; peer queries such as BGP can describe
209relationships Forward models beyond discovery protocols.
210
211If `search_nqe_queries` or `list_nqe_queries` reports that the query index is
212empty, do this only in a persistent OpenClaw session and only after user
213confirmation:
214
2151. Run `hydrate_database` with `regenerate_embeddings: false`.
2162. Run `refresh_query_index`.
2173. Retry `search_nqe_queries` or `list_nqe_queries`.
218
219## Safety Rules
220
221Default to read-only Forward tools. Require explicit human confirmation before
222tools that create, update, delete, clear, hydrate, rebuild, start/cancel
223collection, or set persistent defaults. This includes collector/source,
224credential, network, snapshot, location, entity/relation, observation, local
225cache/index, and `set_default_network` operations. Creating new Forward
226networks requires full org admin privileges; do not use `create_network` unless
227the user explicitly confirms that role. Updating an existing Forward network
228requires network admin privileges.
229
230Never put Forward credentials in repository files. Use `~/.openclaw/.env`.
231For private CA deployments, use `FORWARD_CA_CERT_PATH`; do not disable TLS
232verification.
233
234## Workflows
235
236### Diffs
237
2381. Use `get_snapshot_diff_summary` first for a bounded overview.
2392. Use `get_snapshot_diff` for focused route, ACL, NAT, interface, check,
240 file/config, inventory-query, routing-loop, or vulnerability diffs.
2413. Use `get_nqe_diff` for arbitrary NQE and intent-style query diffs.
2424. Use `get_config_diff` when the user specifically asks for config text drift.
243
244### Blast Radius
245
2461. Use `suggest_blast_radius_sources` if the source name or location filter is
247 uncertain.
2482. Use `get_blast_radius` with `source_device` for a device source, or `source`
249 when the prompt already supplies Forward `LocationFilter` JSON.
2503. Keep `dst_subnets`, `timeout_seconds`, and `paging_options` bounded.
2514. Use blast radius for security/exposure questions; use NQE for tabular
252 snapshot facts and `search_paths_bulk` for specific path traces.
253
254### Checks and CVEs
255
2561. Use `list_checks` with `statuses` such as `FAIL`, `WARN`, or `ERROR` to
257 triage intent/check state for a snapshot.
2582. Use `get_check` for the detailed rows behind a specific failed check.
2593. Use `list_predefined_checks` when the user asks what built-in checks exist.
2604. Use NQE for CVE posture. Prefer `search_nqe_queries` for natural-language
261 discovery, then `run_nqe_query_by_id`.
2625. Useful built-in CVE query paths include `/Security/CVEs/CVE violations by
263 CVE`, `/Security/CVEs/CVE violations by device`,
264 `/Security/CVEs/CVE violation details by device`, and
265 `/Security/CVEs/Vendor CVE metadata`.
2666. Use `get_nqe_diff` for CVE query drift between snapshots. Use
267 `get_snapshot_diff` with `diff_type: "vulnerabilities"` for the Forward
268 vulnerability diff domain.
269
270### Collection and Lab Demo
271
2721. Treat collection setup and start/cancel actions as admin workflows.
2732. Use them only on lab/admin networks or after explicit user confirmation.
2743. Treat collector installation/onboarding as a separate prerequisite. Anyone
275 can install or onboard a collector, but a network admin must assign that
276 collector to the target network. The stable Linux collector download URL is
277 `https://fwd.app/api/software/client?type=LINUX`.
2784. Before starting collection, run `get_collector_status` and
279 `list_classic_devices`.
2805. Prefer `start_collection_task`, poll it with `get_collector_task`, then use
281 `wait_for_latest_snapshot`. Use `start_collection` only when task creation is
282 unavailable in the target deployment.
283
284### Topology Drawing
285
2861. Prefer Forward NQE evidence for collected topology questions: link queries
287 plus relevant protocol-peer queries.
2882. If the NQE result only shows management-plane neighbors or incomplete links in
289 a real or emulated network, use the originating topology source as the edge
290 source and Forward as the collected assurance source.
2913. Use the available lab backend, source-of-truth, inventory, or discovery tool
292 to identify device names, management IPs, physical links, and credentials
293 before Forward collection.
2944. Before `start_collection`, confirm the assigned Forward collector can reach
295 the target management network. If not, the missing step is collector
296 installation, assignment, or routing.
2975. Render a normalized node/edge list with Draw.io, Markmap, or another diagram
298 skill. Never infer links from names or management IPs alone.
299
300## Result Discipline
301
302- Summarize large tables before presenting them.
303- Preserve network IDs, snapshot IDs, query IDs, and device names in the answer.
304- When a path or NQE result is inconclusive, say what data was missing and which
305 next read-only Forward tool should be run.
306- For config and NQE diffs, separate intended changes from unexpected changes.
307- For snapshot diffs, start with counts/summary and drill into the changed
308 domain that matters.