vmware-debug 1.11.1__tar.gz → 1.11.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/.claude-plugin/plugin.json +1 -1
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/.mcp.json +1 -1
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/PKG-INFO +2 -2
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/README-CN.md +3 -1
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/RELEASE_NOTES.md +72 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/pyproject.toml +2 -2
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/server.json +2 -2
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/SKILL.md +3 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/references/event-envelope.md +19 -3
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/_family.py +64 -49
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/_scores.json +67 -34
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/_scoring.py +126 -9
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/test_tool_description_quality.py +27 -12
- vmware_debug-1.11.2/tests/eval/regression/_vsphere_event_vocabulary.py +167 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_capability_grader.py +128 -0
- vmware_debug-1.11.2/tests/eval/regression/test_case_plan_max_steps.py +155 -0
- vmware_debug-1.11.2/tests/eval/regression/test_classification_against_vsphere_vocabulary.py +414 -0
- vmware_debug-1.11.2/tests/eval/regression/test_environment_resolver_isolation.py +174 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/uv.lock +5 -5
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/__init__.py +1 -1
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/mcp_server/server.py +71 -40
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/api.py +15 -3
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/plan.py +16 -3
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/timeline.py +64 -14
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/.gitignore +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/README.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/SECURITY.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/docs/plans/2026-08-28-investigation-layer-design.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/references/agent-guardrails.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/references/capabilities.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/references/cli-reference.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/references/routing.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/references/setup-guide.md +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/__init__.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/__init__.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/_skill.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/conftest.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/test_entity_reachability.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/test_error_actionability.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/capability/test_tool_manifest_budget.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/__init__.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_case_id_non_ascii.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_debug_regressions.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_every_tool_parameter_is_documented.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_evidence_payload_contract.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_host_lifecycle_classification.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_investigation_metrics.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_result_envelope.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_skill_name_aliases.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_spike_resolution.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/eval/regression/test_tool_annotations.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_conclusion.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_evidence.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_grading.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_hypotheses.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_ids.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_plan.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_readiness.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_store.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_timeline_close.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_case_tools.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_knowledge.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_safe_error_passthrough.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/tests/test_timeline.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/cli.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/envelope.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/mcp/__init__.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/mcp/tools.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/mcp_server/__init__.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/__init__.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/__init__.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/conclusion.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/evidence.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/grading.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/hypotheses.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/ids.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/knowledge.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/model.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/payloads.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/readiness.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/sources.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/store.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/cases/timeline.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/ops/skill_names.py +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/rules/evidence_sources.yaml +0 -0
- {vmware_debug-1.11.1 → vmware_debug-1.11.2}/vmware_debug/rules/grading_rules.yaml +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
3
|
"name": "vmware-debug",
|
|
4
4
|
"displayName": "VMware Debug",
|
|
5
|
-
"version": "1.11.
|
|
5
|
+
"version": "1.11.2",
|
|
6
6
|
"description": "Read-only VMware incident correlation: timeline, spikes, root-cause routing. 2 MCP tools.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Wei Zhou",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vmware-debug
|
|
3
|
-
Version: 1.11.
|
|
3
|
+
Version: 1.11.2
|
|
4
4
|
Summary: VMware diagnostic brain — read-only incident triage, log/event correlation, and root-cause routing across the VMware skill family
|
|
5
5
|
Project-URL: Homepage, https://github.com/vmware-skills/VMware-Debug
|
|
6
6
|
Project-URL: Repository, https://github.com/vmware-skills/VMware-Debug
|
|
@@ -18,7 +18,7 @@ Requires-Dist: mcp[cli]<2.0,>=1.10
|
|
|
18
18
|
Requires-Dist: pyyaml<7.0,>=6.0
|
|
19
19
|
Requires-Dist: rich<15.0,>=13.0
|
|
20
20
|
Requires-Dist: typer<1.0,>=0.12
|
|
21
|
-
Requires-Dist: vmware-policy<2.0,>=1.
|
|
21
|
+
Requires-Dist: vmware-policy<2.0,>=1.11.0
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
|
|
24
24
|
<!-- mcp-name: io.github.vmware-skills/vmware-debug -->
|
|
@@ -33,7 +33,9 @@ vmware-debug categories # 看它能诊断哪些症状类别
|
|
|
33
33
|
- `list_symptom_categories`:症状类别及对应的排查路由(不知道查什么时用它)
|
|
34
34
|
|
|
35
35
|
**事件信封**:`{ts, source, severity, entity, text, fields}`。agent 把各源事件归一成此形状再交给
|
|
36
|
-
debug;debug
|
|
36
|
+
debug;debug 因此与其它包零运行时依赖。**请把每条事件的 `event_type` 保留在 `fields` 里**——
|
|
37
|
+
分类器除了正文之外也匹配它,而现代 vSphere 多数事件是 `EventEx`:正文是一句通用套话,
|
|
38
|
+
真正说明「这是什么事件」的只有 `eventTypeId`。
|
|
37
39
|
|
|
38
40
|
## 安全
|
|
39
41
|
|
|
@@ -1,3 +1,75 @@
|
|
|
1
|
+
## v1.11.2 — the resolver hijack, the discarded event identifier, and a parameter that did nothing
|
|
2
|
+
|
|
3
|
+
Three findings from the 2026-08-30 real-hardware re-test.
|
|
4
|
+
|
|
5
|
+
**Importing this package no longer disables another skill's policy rules.**
|
|
6
|
+
`vmware_debug.mcp_server.server` registered a `vmware_policy` environment
|
|
7
|
+
resolver at import time, answering `local` for every target it was asked about.
|
|
8
|
+
That slot is process-global — one function for every skill in the interpreter —
|
|
9
|
+
so in an MCP host that loads several of these skills, importing vmware-debug
|
|
10
|
+
replaced whatever a sibling had installed and every one of that sibling's targets
|
|
11
|
+
began resolving to `local`. A rule scoped to `environments: [production]` then
|
|
12
|
+
matches nothing, and denies nothing. The re-test measured a rule going DENY to
|
|
13
|
+
ALLOW that way.
|
|
14
|
+
|
|
15
|
+
The registration is gone rather than moved. The old note here argued it sat at
|
|
16
|
+
import so `build_server()` would not re-register a constant; that answered the
|
|
17
|
+
wrong question, since re-registering costs nothing and registering at all costs a
|
|
18
|
+
sibling its rules. vmware-debug has no target config and no connection, so
|
|
19
|
+
`resolve_environment`'s documented default — unlabeled, matching no
|
|
20
|
+
environment-scoped rule — is the honest answer.
|
|
21
|
+
|
|
22
|
+
**`case_plan(max_steps=...)` now reaches the planner.** The MCP tool declared the
|
|
23
|
+
parameter and called `api.plan()` without it, so every plan came back at 6 steps
|
|
24
|
+
however many were asked for, while the ops layer has always honoured the cap and
|
|
25
|
+
a storage case has fourteen reachable tools. The result's own note ended with
|
|
26
|
+
"pass a larger max_steps to see them" — advice to do the one thing that could not
|
|
27
|
+
work. Values below 1 are now refused rather than obeyed: `[:0]` returns an empty
|
|
28
|
+
plan, which reads as "nothing left to fetch", and `[:-3]` silently drops the last
|
|
29
|
+
three steps. The default now comes from one constant instead of being typed out
|
|
30
|
+
at three layers.
|
|
31
|
+
|
|
32
|
+
**Symptom classification reads the event's own identifier.** `normalize_event`
|
|
33
|
+
has always preserved `event_type` / `eventTypeId` in `fields`, and the classifier
|
|
34
|
+
read only the prose. Modern vSphere sends most events as `EventEx`, where the
|
|
35
|
+
message is generic boilerplate ("Issue detected on esx01") and the whole identity
|
|
36
|
+
is a string like `esx.problem.scsi.device.io.latency.high` — which names its
|
|
37
|
+
subsystem outright. vmware-monitor hit this on real hardware and fixed it on its
|
|
38
|
+
side; vmware-debug had the same defect on the receiving side. camelCase and
|
|
39
|
+
punctuation are split so a two-word keyword can reach an identifier
|
|
40
|
+
(`HostShutdownEvent` becomes `host shutdown`); nothing here decides a category,
|
|
41
|
+
it only makes an existing keyword reachable.
|
|
42
|
+
|
|
43
|
+
**On the unclassified share: measured, explained, and not inflated.** Against
|
|
44
|
+
pyVmomi's registry of all 427 vSphere event types the taxonomy reads 124 and
|
|
45
|
+
misses 303, and the misses are not subsystems it lacks. They are events whose
|
|
46
|
+
subsystem already has a category, spelled the way a server records a fact rather
|
|
47
|
+
than the way an operator describes a symptom: `VmPoweredOnEvent` against "power
|
|
48
|
+
on", `HostCnxFailedTimeoutEvent` against "connection lost", `DasHostFailedEvent`
|
|
49
|
+
against "high availability", `VmMigratedEvent` against "vmotion". No keywords were
|
|
50
|
+
added. Sixty more phrases would close today's list and lose on the next vSphere
|
|
51
|
+
release, which is what a hand-maintained vocabulary does — so the taxonomy is
|
|
52
|
+
unchanged, the finding is recorded as a regression test with the corpus and the
|
|
53
|
+
named examples, and a test fails if the phrase list is later padded.
|
|
54
|
+
|
|
55
|
+
Reading the identifier is worth exactly one type out of 427 on this corpus,
|
|
56
|
+
because for a classic event the message and the class name say the same words.
|
|
57
|
+
That number is pinned too, so no coverage claim can be borrowed from it. The
|
|
58
|
+
value is on `EventEx`, which a list of class names cannot represent.
|
|
59
|
+
|
|
60
|
+
What did change is the advice. The coverage note told the reader that unmatched
|
|
61
|
+
events might "name a subsystem this taxonomy does not know" and to go find that
|
|
62
|
+
subsystem's read tools — a false premise followed by a wasted call. It now names
|
|
63
|
+
the actual mechanism, says to pass `event_type`, and says to force the category
|
|
64
|
+
with `case_plan(category=...)` when you already believe you know it.
|
|
65
|
+
|
|
66
|
+
The re-test also reported a missing `causal_chains` key "which the docs imply".
|
|
67
|
+
No document in this repository promises one, and `incident_timeline`'s RETURNS
|
|
68
|
+
list is accurate. Rather than invent a key or simply reply that the claim is
|
|
69
|
+
wrong, the checkable form of the concern is now a test: whatever the docstring
|
|
70
|
+
lists, the tool returns, and whatever the tool returns, the docstring lists.
|
|
71
|
+
|
|
72
|
+
|
|
1
73
|
## v1.11.1 — the schema an agent reads now carries the descriptions
|
|
2
74
|
|
|
3
75
|
Parameter descriptions reach the JSON schema for the first time. An MCP client
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vmware-debug"
|
|
7
|
-
version = "1.11.
|
|
7
|
+
version = "1.11.2"
|
|
8
8
|
description = "VMware diagnostic brain — read-only incident triage, log/event correlation, and root-cause routing across the VMware skill family"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -21,7 +21,7 @@ dependencies = [
|
|
|
21
21
|
"typer>=0.12,<1.0",
|
|
22
22
|
"rich>=13.0,<15.0",
|
|
23
23
|
"mcp[cli]>=1.10,<2.0",
|
|
24
|
-
"vmware-policy>=1.
|
|
24
|
+
"vmware-policy>=1.11.0,<2.0",
|
|
25
25
|
# Imported directly by ops/cases/grading.py for the rules file. It has
|
|
26
26
|
# always arrived transitively via vmware-policy; a package should
|
|
27
27
|
# declare what it imports rather than rely on a dependency's dependency.
|
|
@@ -7,12 +7,12 @@
|
|
|
7
7
|
"url": "https://github.com/vmware-skills/VMware-Debug",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.11.
|
|
10
|
+
"version": "1.11.2",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "vmware-debug",
|
|
15
|
-
"version": "1.11.
|
|
15
|
+
"version": "1.11.2",
|
|
16
16
|
"runtimeHint": "uvx",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{
|
|
@@ -133,6 +133,9 @@ The four writes go to `$OPS_HOME` (default `~/.vmware/cases/`) and nowhere else.
|
|
|
133
133
|
**Event envelope** (input to `incident_timeline`): `{ts, source, severity, entity, text, fields}`.
|
|
134
134
|
See `references/event-envelope.md`. The agent normalises each source's events into this
|
|
135
135
|
shape; debug stays source-agnostic and has no dependency on the other packages.
|
|
136
|
+
Keep each event's `event_type` in `fields` — the classifier matches it as well as
|
|
137
|
+
the message, and on a modern `EventEx` it is the only thing that says what the
|
|
138
|
+
event was.
|
|
136
139
|
|
|
137
140
|
## The Investigation Ledger
|
|
138
141
|
|
{vmware_debug-1.11.1 → vmware_debug-1.11.2}/skills/vmware-debug/references/event-envelope.md
RENAMED
|
@@ -14,7 +14,8 @@ runtime dependency** on the other packages (no version lockstep, no heavy instal
|
|
|
14
14
|
"severity": "error",
|
|
15
15
|
"entity": "vm-web01",
|
|
16
16
|
"text": "Device naa.600... performance has deteriorated",
|
|
17
|
-
"fields": { "
|
|
17
|
+
"fields": { "event_type": "esx.problem.scsi.device.io.latency.high",
|
|
18
|
+
"host": "esxi-03", "datastore": "ds1" }
|
|
18
19
|
}
|
|
19
20
|
```
|
|
20
21
|
|
|
@@ -24,8 +25,23 @@ runtime dependency** on the other packages (no version lockstep, no heavy instal
|
|
|
24
25
|
| `source` | string | `monitor` \| `aria` \| `loginsight` \| `nsx` \| `nsx-security` \| `storage` \| ... The catalogue in `rules/evidence_sources.yaml` spells the same skills `vmware-monitor`, `vmware-aria`, `vmware-log-insight`. Both spellings are understood wherever a skill is named — `case_readiness(available_skills=...)`, and the grader's count of independent sources, which treats two spellings of one skill as one source. |
|
|
25
26
|
| `severity` | string | Free text; normalised to `critical`/`error`/`warning`/`info`/`unknown`. |
|
|
26
27
|
| `entity` | string | The object the event is about (VM/host/datastore). May be empty. |
|
|
27
|
-
| `text` | string | Human-readable message
|
|
28
|
-
| `fields` | object | Any source-specific extras; preserved, never dropped. |
|
|
28
|
+
| `text` | string | Human-readable message. Matched by the symptom classifier. |
|
|
29
|
+
| `fields` | object | Any source-specific extras; preserved, never dropped. `event_type` / `eventTypeId` is matched by the classifier too — see below. |
|
|
30
|
+
|
|
31
|
+
### `fields.event_type` is worth passing
|
|
32
|
+
|
|
33
|
+
The classifier matches the identifier as well as the prose, with camelCase and
|
|
34
|
+
dots split so a two-word keyword can reach it (`HostShutdownEvent` → `host
|
|
35
|
+
shutdown`, `esx.problem.cpu.ready` → `cpu ready`).
|
|
36
|
+
|
|
37
|
+
For a classic vCenter event this changes almost nothing — `VmMigratedEvent` and
|
|
38
|
+
its message say the same words. It matters for `EventEx`, which is how modern
|
|
39
|
+
vSphere emits most events: the message is generic boilerplate ("Issue detected on
|
|
40
|
+
esx01") and the whole identity is in `eventTypeId`. Drop that field and a storage
|
|
41
|
+
incident arrives as an unreadable event; keep it and it classifies as storage.
|
|
42
|
+
|
|
43
|
+
`vmware-monitor`'s `get_events` returns it as `event_type`; passing the row
|
|
44
|
+
through unchanged is enough.
|
|
29
45
|
|
|
30
46
|
The normaliser is tolerant of common field-name variants (e.g. `timestamp`,
|
|
31
47
|
`createTime`, `startTimeUTC` for `ts`; `criticality`, `level` for `severity`;
|
|
@@ -11,31 +11,34 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
FAMILY_TOOLS: dict[str, frozenset[str]] = {
|
|
13
13
|
'vmware-aiops': frozenset({
|
|
14
|
-
'acknowledge_vcenter_alarm', 'attach_iso_to_vm', 'batch_clone_vms',
|
|
14
|
+
'acknowledge_vcenter_alarm', 'add_host_vmk', 'attach_iso_to_vm', 'batch_clone_vms',
|
|
15
15
|
'batch_deploy_from_spec', 'batch_linked_clone_vms', 'browse_datastore',
|
|
16
16
|
'cluster_add_host', 'cluster_configure', 'cluster_create', 'cluster_delete',
|
|
17
17
|
'cluster_health_summary', 'cluster_info', 'cluster_remove_host',
|
|
18
|
-
'convert_vm_to_template', '
|
|
19
|
-
'
|
|
20
|
-
'
|
|
21
|
-
'
|
|
22
|
-
'
|
|
23
|
-
'
|
|
24
|
-
'
|
|
18
|
+
'convert_vm_to_template', 'create_drs_rule', 'create_dvs_portgroup',
|
|
19
|
+
'cross_vcenter_attention', 'datastore_investigation_bundle', 'delete_drs_rule',
|
|
20
|
+
'deploy_linked_clone', 'deploy_vm_from_ova', 'deploy_vm_from_template',
|
|
21
|
+
'host_investigation_bundle', 'list_drs_rules', 'list_dvs_portgroups',
|
|
22
|
+
'list_host_vmks', 'list_vcenter_alarms', 'remove_host_vmk', 'reset_vcenter_alarm',
|
|
23
|
+
'scan_datastore_images', 'set_drs_rule_enabled', 'set_vmk_service', 'vm_apply_plan',
|
|
24
|
+
'vm_cancel_ttl', 'vm_clean_slate', 'vm_clone', 'vm_create', 'vm_create_plan',
|
|
25
|
+
'vm_create_snapshot', 'vm_delete', 'vm_delete_snapshot', 'vm_guest_download',
|
|
26
|
+
'vm_guest_exec', 'vm_guest_exec_output', 'vm_guest_provision', 'vm_guest_upload',
|
|
25
27
|
'vm_investigation_bundle', 'vm_list_plans', 'vm_list_snapshots', 'vm_list_ttl',
|
|
26
28
|
'vm_migrate', 'vm_power_off', 'vm_power_on', 'vm_reconfigure', 'vm_revert_snapshot',
|
|
27
|
-
'vm_rollback_plan', 'vm_set_ttl', 'vm_task_status',
|
|
29
|
+
'vm_rollback_plan', 'vm_set_ttl', 'vm_task_status', 'vmk_ping',
|
|
28
30
|
}),
|
|
29
31
|
'vmware-aria': frozenset({
|
|
30
32
|
'acknowledge_alert', 'cancel_alert', 'create_alert_definition',
|
|
31
|
-
'delete_alert_definition', 'delete_report', '
|
|
32
|
-
'
|
|
33
|
-
'
|
|
34
|
-
'
|
|
35
|
-
'
|
|
36
|
-
'
|
|
37
|
-
'
|
|
38
|
-
'
|
|
33
|
+
'delete_alert_definition', 'delete_report', 'findings_list',
|
|
34
|
+
'fleet_certificate_list', 'fleet_domain_list', 'fleet_password_account_list',
|
|
35
|
+
'generate_report', 'get_alert', 'get_aria_health', 'get_capacity_overview',
|
|
36
|
+
'get_remaining_capacity', 'get_report', 'get_resource', 'get_resource_health',
|
|
37
|
+
'get_resource_metrics', 'get_resource_riskbadge', 'get_time_remaining',
|
|
38
|
+
'get_top_consumers', 'investigate_alert', 'list_alert_definitions', 'list_alerts',
|
|
39
|
+
'list_anomalies', 'list_collector_groups', 'list_report_definitions',
|
|
40
|
+
'list_reports', 'list_resources', 'list_rightsizing_recommendations',
|
|
41
|
+
'list_symptom_definitions', 'promql_query', 'set_alert_definition_state',
|
|
39
42
|
}),
|
|
40
43
|
'vmware-avi': frozenset({
|
|
41
44
|
'ako_amko_status', 'ako_clusters', 'ako_config_diff', 'ako_config_show',
|
|
@@ -47,11 +50,15 @@ FAMILY_TOOLS: dict[str, frozenset[str]] = {
|
|
|
47
50
|
'vs_status', 'vs_toggle',
|
|
48
51
|
}),
|
|
49
52
|
'vmware-debug': frozenset({
|
|
50
|
-
'
|
|
53
|
+
'case_close', 'case_get', 'case_grade', 'case_hypotheses', 'case_knowledge',
|
|
54
|
+
'case_list', 'case_open', 'case_plan', 'case_readiness', 'case_record_gap',
|
|
55
|
+
'case_submit_evidence', 'case_timeline', 'incident_timeline',
|
|
56
|
+
'list_symptom_categories',
|
|
51
57
|
}),
|
|
52
58
|
'vmware-harden': frozenset({
|
|
53
|
-
'
|
|
54
|
-
'
|
|
59
|
+
'describe_stig_content_sync', 'get_baseline_rules', 'get_remediation',
|
|
60
|
+
'list_baselines', 'list_drift_events', 'list_stig_controls', 'list_violations',
|
|
61
|
+
'scan_target',
|
|
55
62
|
}),
|
|
56
63
|
'vmware-log-insight': frozenset({
|
|
57
64
|
'alert_get', 'alert_history', 'alert_list', 'log_aggregate', 'log_fields',
|
|
@@ -59,12 +66,14 @@ FAMILY_TOOLS: dict[str, frozenset[str]] = {
|
|
|
59
66
|
}),
|
|
60
67
|
'vmware-monitor': frozenset({
|
|
61
68
|
'active_sessions', 'active_tasks', 'certificate_status', 'cluster_health_summary',
|
|
62
|
-
'
|
|
63
|
-
'
|
|
64
|
-
'
|
|
69
|
+
'cluster_last_apply_result', 'cluster_patch_compliance', 'cross_vcenter_attention',
|
|
70
|
+
'datastore_capacity', 'datastore_investigation_bundle', 'get_alarms', 'get_events',
|
|
71
|
+
'get_host_sensors', 'get_host_services', 'host_investigation_bundle',
|
|
72
|
+
'host_log_scan', 'host_memory_tiering', 'host_performance', 'license_status',
|
|
65
73
|
'list_all_clusters', 'list_all_datastores', 'list_all_networks', 'list_esxi_hosts',
|
|
66
74
|
'list_virtual_machines', 'ntp_status', 'resource_pool_usage', 'snapshot_aging',
|
|
67
|
-
'
|
|
75
|
+
'vcenter_deployment_size', 'vm_info', 'vm_investigation_bundle',
|
|
76
|
+
'vm_list_snapshots', 'vm_performance',
|
|
68
77
|
}),
|
|
69
78
|
'vmware-nsx': frozenset({
|
|
70
79
|
'configure_tier0_bgp', 'create_ip_pool', 'create_nat_rule', 'create_segment',
|
|
@@ -82,9 +91,9 @@ FAMILY_TOOLS: dict[str, frozenset[str]] = {
|
|
|
82
91
|
'apply_vm_tag', 'create_dfw_policy', 'create_dfw_rule', 'create_group',
|
|
83
92
|
'delete_dfw_policy', 'delete_dfw_rule', 'delete_group', 'get_dfw_policy',
|
|
84
93
|
'get_dfw_rule_stats', 'get_group', 'get_idps_status', 'get_traceflow_result',
|
|
85
|
-
'
|
|
86
|
-
'
|
|
87
|
-
'update_dfw_rule',
|
|
94
|
+
'list_dfw_exclusions', 'list_dfw_policies', 'list_dfw_rules', 'list_groups',
|
|
95
|
+
'list_idps_profiles', 'list_vm_tags', 'remove_vm_tag', 'run_traceflow',
|
|
96
|
+
'update_dfw_policy', 'update_dfw_rule',
|
|
88
97
|
}),
|
|
89
98
|
'vmware-pilot': frozenset({
|
|
90
99
|
'approve', 'cancel_workflow', 'confirm_draft', 'create_workflow', 'design_workflow',
|
|
@@ -95,7 +104,7 @@ FAMILY_TOOLS: dict[str, frozenset[str]] = {
|
|
|
95
104
|
'browse_datastore', 'list_all_datastores', 'list_cached_images',
|
|
96
105
|
'scan_datastore_images', 'storage_iscsi_add_target', 'storage_iscsi_enable',
|
|
97
106
|
'storage_iscsi_remove_target', 'storage_iscsi_status', 'storage_rescan',
|
|
98
|
-
'vsan_capacity', 'vsan_health',
|
|
107
|
+
'vsan_capacity', 'vsan_efficiency', 'vsan_health',
|
|
99
108
|
}),
|
|
100
109
|
'vmware-vks': frozenset({
|
|
101
110
|
'check_vks_compatibility', 'create_namespace', 'create_tkc_cluster',
|
|
@@ -103,22 +112,24 @@ FAMILY_TOOLS: dict[str, frozenset[str]] = {
|
|
|
103
112
|
'get_supervisor_kubeconfig', 'get_supervisor_status', 'get_tkc_available_versions',
|
|
104
113
|
'get_tkc_cluster', 'get_tkc_kubeconfig', 'list_namespace_storage_usage',
|
|
105
114
|
'list_namespaces', 'list_supervisor_storage_policies', 'list_tkc_clusters',
|
|
106
|
-
'list_vm_classes', '
|
|
115
|
+
'list_vm_classes', 'list_vm_groups', 'list_vm_network_interfaces',
|
|
116
|
+
'list_vm_snapshots', 'scale_tkc_cluster', 'update_namespace', 'upgrade_tkc_cluster',
|
|
107
117
|
}),
|
|
108
118
|
}
|
|
109
119
|
|
|
110
120
|
FAMILY_COMMANDS: dict[str, frozenset[str]] = {
|
|
111
121
|
'vmware-aiops': frozenset({
|
|
112
122
|
'alarm acknowledge', 'alarm list', 'alarm reset', 'attention', 'cluster add-host',
|
|
113
|
-
'cluster configure', 'cluster create', 'cluster delete', 'cluster
|
|
114
|
-
'cluster
|
|
115
|
-
'
|
|
116
|
-
'
|
|
117
|
-
'deploy
|
|
118
|
-
'
|
|
119
|
-
'
|
|
120
|
-
'
|
|
121
|
-
'vm
|
|
123
|
+
'cluster configure', 'cluster create', 'cluster delete', 'cluster drs-rule-create',
|
|
124
|
+
'cluster drs-rule-delete', 'cluster drs-rule-set', 'cluster drs-rules',
|
|
125
|
+
'cluster info', 'cluster remove-host', 'daemon start', 'daemon status',
|
|
126
|
+
'daemon stop', 'datastore browse', 'datastore scan-images', 'deploy batch',
|
|
127
|
+
'deploy batch-clone', 'deploy iso', 'deploy linked-clone', 'deploy mark-template',
|
|
128
|
+
'deploy ova', 'deploy template', 'doctor', 'hub status', 'init',
|
|
129
|
+
'investigate datastore', 'investigate host', 'investigate vm', 'mcp',
|
|
130
|
+
'mcp-config generate', 'mcp-config install', 'mcp-config list', 'plan list',
|
|
131
|
+
'scan now', 'summary', 'vm cancel-ttl', 'vm clean-slate', 'vm clone', 'vm create',
|
|
132
|
+
'vm delete', 'vm guest-download', 'vm guest-exec', 'vm guest-upload', 'vm list-ttl',
|
|
122
133
|
'vm migrate', 'vm power-off', 'vm power-on', 'vm reconfigure', 'vm set-ttl',
|
|
123
134
|
'vm snapshot-create', 'vm snapshot-delete', 'vm snapshot-list',
|
|
124
135
|
'vm snapshot-revert', 'vm task-status',
|
|
@@ -126,10 +137,11 @@ FAMILY_COMMANDS: dict[str, frozenset[str]] = {
|
|
|
126
137
|
'vmware-aria': frozenset({
|
|
127
138
|
'alert acknowledge', 'alert cancel', 'alert definitions', 'alert get', 'alert list',
|
|
128
139
|
'anomaly list', 'anomaly risk', 'capacity overview', 'capacity remaining',
|
|
129
|
-
'capacity rightsizing', 'capacity time-remaining', 'doctor', '
|
|
130
|
-
'
|
|
131
|
-
'
|
|
132
|
-
'
|
|
140
|
+
'capacity rightsizing', 'capacity time-remaining', 'doctor', 'fleet certificates',
|
|
141
|
+
'fleet domains', 'fleet findings', 'fleet passwords', 'fleet promql',
|
|
142
|
+
'health collectors', 'health status', 'init', 'mcp', 'report definitions',
|
|
143
|
+
'report delete', 'report generate', 'report get', 'report list', 'resource get',
|
|
144
|
+
'resource health', 'resource list', 'resource metrics', 'resource top',
|
|
133
145
|
}),
|
|
134
146
|
'vmware-avi': frozenset({
|
|
135
147
|
'ako amko-status', 'ako clusters', 'ako config-diff', 'ako config-show',
|
|
@@ -145,7 +157,8 @@ FAMILY_COMMANDS: dict[str, frozenset[str]] = {
|
|
|
145
157
|
}),
|
|
146
158
|
'vmware-harden': frozenset({
|
|
147
159
|
'advise', 'apply', 'baseline import', 'baseline list', 'baseline validate',
|
|
148
|
-
'doctor', 'drift', 'mcp', 'report', 'scan', '
|
|
160
|
+
'doctor', 'drift', 'mcp', 'report', 'scan', 'stig controls', 'stig sync-info',
|
|
161
|
+
'web',
|
|
149
162
|
}),
|
|
150
163
|
'vmware-log-insight': frozenset({
|
|
151
164
|
'aggregate', 'alert get', 'alert history', 'alert list', 'doctor', 'fields', 'mcp',
|
|
@@ -153,13 +166,14 @@ FAMILY_COMMANDS: dict[str, frozenset[str]] = {
|
|
|
153
166
|
}),
|
|
154
167
|
'vmware-monitor': frozenset({
|
|
155
168
|
'activity sessions', 'activity tasks', 'attention', 'capacity datastores',
|
|
156
|
-
'capacity pools', 'daemon start', 'daemon status', 'daemon stop', '
|
|
157
|
-
'health alarms', 'health events', 'health sensors', 'health services',
|
|
169
|
+
'capacity pools', 'daemon start', 'daemon status', 'daemon stop', 'deployment-size',
|
|
170
|
+
'doctor', 'health alarms', 'health events', 'health sensors', 'health services',
|
|
158
171
|
'infra certs', 'infra licenses', 'infra ntp', 'init', 'inventory clusters',
|
|
159
172
|
'inventory datastores', 'inventory hosts', 'inventory networks', 'inventory vms',
|
|
160
173
|
'investigate datastore', 'investigate host', 'investigate vm', 'mcp',
|
|
161
|
-
'mcp-config generate', 'mcp-config list', '
|
|
162
|
-
'
|
|
174
|
+
'mcp-config generate', 'mcp-config list', 'memory tiering', 'patch compliance',
|
|
175
|
+
'patch last-apply', 'perf hosts', 'perf vms', 'scan now', 'snapshots aging',
|
|
176
|
+
'summary', 'vm info', 'vm snapshot-list',
|
|
163
177
|
}),
|
|
164
178
|
'vmware-nsx': frozenset({
|
|
165
179
|
'doctor', 'gateway configure-tier0-bgp', 'gateway create-tier1',
|
|
@@ -188,14 +202,15 @@ FAMILY_COMMANDS: dict[str, frozenset[str]] = {
|
|
|
188
202
|
'vmware-storage': frozenset({
|
|
189
203
|
'datastore browse', 'datastore list', 'datastore scan-images', 'doctor', 'init',
|
|
190
204
|
'iscsi add-target', 'iscsi enable', 'iscsi remove-target', 'iscsi rescan',
|
|
191
|
-
'iscsi status', 'mcp', 'vsan capacity', 'vsan health',
|
|
205
|
+
'iscsi status', 'mcp', 'vsan capacity', 'vsan efficiency', 'vsan health',
|
|
192
206
|
}),
|
|
193
207
|
'vmware-vks': frozenset({
|
|
194
208
|
'check', 'harbor', 'init', 'kubeconfig get', 'kubeconfig supervisor', 'mcp',
|
|
195
209
|
'namespace create', 'namespace delete', 'namespace get', 'namespace list',
|
|
196
210
|
'namespace update', 'namespace vm-classes', 'preflight-auth', 'storage',
|
|
197
211
|
'supervisor status', 'supervisor storage-policies', 'tkc create', 'tkc delete',
|
|
198
|
-
'tkc get', 'tkc list', 'tkc scale', 'tkc upgrade', 'tkc versions',
|
|
212
|
+
'tkc get', 'tkc list', 'tkc scale', 'tkc upgrade', 'tkc versions', 'vm groups',
|
|
213
|
+
'vm nics', 'vm snapshots',
|
|
199
214
|
}),
|
|
200
215
|
}
|
|
201
216
|
|
|
@@ -135,7 +135,7 @@
|
|
|
135
135
|
"names_artifact",
|
|
136
136
|
"states_remedy"
|
|
137
137
|
],
|
|
138
|
-
"where": "plan.py:
|
|
138
|
+
"where": "plan.py:97"
|
|
139
139
|
},
|
|
140
140
|
{
|
|
141
141
|
"message": "evidence_sources.yaml at {} is missing 'classes' or 'routing'. An empty catalogue would make every r",
|
|
@@ -179,39 +179,64 @@
|
|
|
179
179
|
}
|
|
180
180
|
],
|
|
181
181
|
"per_dimension_pct": {
|
|
182
|
-
"names_artifact":
|
|
183
|
-
"names_input": 95.
|
|
184
|
-
"states_remedy":
|
|
182
|
+
"names_artifact": 37.2,
|
|
183
|
+
"names_input": 95.3,
|
|
184
|
+
"states_remedy": 62.8
|
|
185
185
|
},
|
|
186
|
-
"raise_sites":
|
|
186
|
+
"raise_sites": 43
|
|
187
187
|
},
|
|
188
|
-
"maximum":
|
|
188
|
+
"maximum": 129,
|
|
189
189
|
"pct": 65.1,
|
|
190
190
|
"unit": "points",
|
|
191
|
-
"value":
|
|
191
|
+
"value": 84
|
|
192
192
|
},
|
|
193
193
|
"manifest_context_headroom": {
|
|
194
194
|
"detail": {
|
|
195
195
|
"heaviest_tools": {
|
|
196
|
-
"case_open":
|
|
197
|
-
"case_plan":
|
|
198
|
-
"case_record_gap":
|
|
199
|
-
"case_submit_evidence":
|
|
200
|
-
"incident_timeline":
|
|
196
|
+
"case_open": 521,
|
|
197
|
+
"case_plan": 499,
|
|
198
|
+
"case_record_gap": 410,
|
|
199
|
+
"case_submit_evidence": 971,
|
|
200
|
+
"incident_timeline": 521
|
|
201
201
|
},
|
|
202
|
-
"manifest_tokens":
|
|
203
|
-
"mean_tokens_per_tool":
|
|
202
|
+
"manifest_tokens": 5160,
|
|
203
|
+
"mean_tokens_per_tool": 368.6,
|
|
204
204
|
"reference_context": 16384,
|
|
205
205
|
"tool_count": 14
|
|
206
206
|
},
|
|
207
207
|
"maximum": 16384,
|
|
208
|
-
"pct":
|
|
208
|
+
"pct": 68.5,
|
|
209
209
|
"unit": "tokens",
|
|
210
|
-
"value":
|
|
210
|
+
"value": 11224
|
|
211
211
|
},
|
|
212
212
|
"parameter_documentation_coverage": {
|
|
213
213
|
"detail": {
|
|
214
|
-
"undocumented_by_tool": {}
|
|
214
|
+
"undocumented_by_tool": {},
|
|
215
|
+
"value_set_candidates": {
|
|
216
|
+
"case_open.objects": [
|
|
217
|
+
"host-12",
|
|
218
|
+
"vm-web01"
|
|
219
|
+
],
|
|
220
|
+
"case_plan.available_skills": [
|
|
221
|
+
"monitor",
|
|
222
|
+
"vmware-monitor"
|
|
223
|
+
],
|
|
224
|
+
"case_readiness.available_skills": [
|
|
225
|
+
"monitor",
|
|
226
|
+
"unrecognised_skills",
|
|
227
|
+
"vmware-monitor"
|
|
228
|
+
],
|
|
229
|
+
"case_submit_evidence.payload": [
|
|
230
|
+
"events",
|
|
231
|
+
"items",
|
|
232
|
+
"rows"
|
|
233
|
+
],
|
|
234
|
+
"case_submit_evidence.time_source": [
|
|
235
|
+
"client",
|
|
236
|
+
"host",
|
|
237
|
+
"vcenter"
|
|
238
|
+
]
|
|
239
|
+
}
|
|
215
240
|
},
|
|
216
241
|
"maximum": 45,
|
|
217
242
|
"pct": 100.0,
|
|
@@ -222,12 +247,12 @@
|
|
|
222
247
|
"detail": {
|
|
223
248
|
"ceiling": 350,
|
|
224
249
|
"over_ceiling": {
|
|
225
|
-
"case_open":
|
|
226
|
-
"case_plan":
|
|
227
|
-
"case_record_gap":
|
|
228
|
-
"case_submit_evidence":
|
|
229
|
-
"case_timeline":
|
|
230
|
-
"incident_timeline":
|
|
250
|
+
"case_open": 521,
|
|
251
|
+
"case_plan": 499,
|
|
252
|
+
"case_record_gap": 410,
|
|
253
|
+
"case_submit_evidence": 971,
|
|
254
|
+
"case_timeline": 393,
|
|
255
|
+
"incident_timeline": 521
|
|
231
256
|
}
|
|
232
257
|
},
|
|
233
258
|
"maximum": 14,
|
|
@@ -275,15 +300,15 @@
|
|
|
275
300
|
"hypotheses.py:70"
|
|
276
301
|
]
|
|
277
302
|
},
|
|
278
|
-
"maximum":
|
|
303
|
+
"maximum": 28,
|
|
279
304
|
"pct": 100.0,
|
|
280
305
|
"unit": "messages",
|
|
281
|
-
"value":
|
|
306
|
+
"value": 28
|
|
282
307
|
},
|
|
283
308
|
"teaching_error_rate": {
|
|
284
309
|
"detail": {},
|
|
285
|
-
"maximum":
|
|
286
|
-
"pct":
|
|
310
|
+
"maximum": 43,
|
|
311
|
+
"pct": 34.9,
|
|
287
312
|
"unit": "messages",
|
|
288
313
|
"value": 15
|
|
289
314
|
},
|
|
@@ -291,36 +316,44 @@
|
|
|
291
316
|
"detail": {
|
|
292
317
|
"per_dimension_pct": {
|
|
293
318
|
"args": 100.0,
|
|
294
|
-
"gotcha":
|
|
319
|
+
"gotcha": 85.7,
|
|
295
320
|
"marker": 100.0,
|
|
296
|
-
"next_hop":
|
|
321
|
+
"next_hop": 57.1,
|
|
297
322
|
"what": 100.0,
|
|
298
323
|
"when": 92.9
|
|
299
324
|
},
|
|
300
325
|
"tools_graded": 14,
|
|
301
326
|
"weakest_tools": {
|
|
302
|
-
"case_close": [
|
|
303
|
-
|
|
304
|
-
|
|
327
|
+
"case_close": [
|
|
328
|
+
"next_hop"
|
|
329
|
+
],
|
|
330
|
+
"case_get": [
|
|
331
|
+
"gotcha"
|
|
332
|
+
],
|
|
333
|
+
"case_grade": [
|
|
334
|
+
"next_hop"
|
|
335
|
+
],
|
|
305
336
|
"case_hypotheses": [],
|
|
306
337
|
"case_knowledge": [
|
|
307
338
|
"next_hop"
|
|
308
339
|
],
|
|
309
340
|
"case_list": [
|
|
341
|
+
"gotcha",
|
|
310
342
|
"next_hop"
|
|
311
343
|
],
|
|
312
344
|
"case_readiness": [
|
|
313
345
|
"next_hop"
|
|
314
346
|
],
|
|
315
347
|
"case_record_gap": [
|
|
348
|
+
"next_hop",
|
|
316
349
|
"when"
|
|
317
350
|
]
|
|
318
351
|
}
|
|
319
352
|
},
|
|
320
353
|
"maximum": 84,
|
|
321
|
-
"pct":
|
|
354
|
+
"pct": 89.3,
|
|
322
355
|
"unit": "points",
|
|
323
|
-
"value":
|
|
356
|
+
"value": 75
|
|
324
357
|
},
|
|
325
358
|
"tool_failure_payload_quality": {
|
|
326
359
|
"detail": {
|