vmware-debug 1.8.5__tar.gz → 1.8.8__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.8.5 → vmware_debug-1.8.8}/PKG-INFO +27 -40
- vmware_debug-1.8.8/README-CN.md +45 -0
- vmware_debug-1.8.8/README.md +62 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/RELEASE_NOTES.md +39 -2
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/SECURITY.md +1 -1
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/pyproject.toml +1 -1
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/server.json +4 -4
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/skills/vmware-debug/SKILL.md +6 -12
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/skills/vmware-debug/references/agent-guardrails.md +3 -40
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/skills/vmware-debug/references/capabilities.md +0 -5
- vmware_debug-1.8.8/skills/vmware-debug/references/setup-guide.md +49 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/_scores.json +14 -16
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/conftest.py +6 -23
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/test_entity_reachability.py +6 -36
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/test_tool_manifest_budget.py +3 -42
- vmware_debug-1.8.8/tests/eval/regression/test_tool_annotations.py +42 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/uv.lock +4 -4
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/__init__.py +1 -1
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/mcp_server/server.py +2 -19
- vmware_debug-1.8.5/README-CN.md +0 -79
- vmware_debug-1.8.5/README.md +0 -75
- vmware_debug-1.8.5/skills/vmware-debug/references/setup-guide.md +0 -90
- vmware_debug-1.8.5/tests/eval/regression/test_declared_environment.py +0 -181
- vmware_debug-1.8.5/tests/eval/regression/test_read_only_mode.py +0 -158
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/.gitignore +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/skills/vmware-debug/references/cli-reference.md +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/skills/vmware-debug/references/event-envelope.md +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/skills/vmware-debug/references/routing.md +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/__init__.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/__init__.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/_family.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/_scoring.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/_skill.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/test_error_actionability.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/capability/test_tool_description_quality.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/regression/__init__.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/regression/test_capability_grader.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/regression/test_debug_regressions.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/eval/regression/test_result_envelope.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/test_safe_error_passthrough.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/tests/test_timeline.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/cli.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/envelope.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/mcp/__init__.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/mcp/tools.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/mcp_server/__init__.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/ops/__init__.py +0 -0
- {vmware_debug-1.8.5 → vmware_debug-1.8.8}/vmware_debug/ops/timeline.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vmware-debug
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.8
|
|
4
4
|
Summary: VMware diagnostic brain — read-only incident triage, log/event correlation, and root-cause routing across the VMware skill family
|
|
5
5
|
Author-email: Wei Zhou <wei-wz.zhou@broadcom.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -16,7 +16,7 @@ Requires-Dist: typer<1.0,>=0.12
|
|
|
16
16
|
Requires-Dist: vmware-policy<2.0,>=1.8.5
|
|
17
17
|
Description-Content-Type: text/markdown
|
|
18
18
|
|
|
19
|
-
<!-- mcp-name: io.github.
|
|
19
|
+
<!-- mcp-name: io.github.vmware-skills/vmware-debug -->
|
|
20
20
|
|
|
21
21
|
# VMware Debug
|
|
22
22
|
|
|
@@ -40,8 +40,6 @@ advisor/executor split.
|
|
|
40
40
|
See [`skills/vmware-debug/SKILL.md`](skills/vmware-debug/SKILL.md) for the full
|
|
41
41
|
methodology, the event-envelope contract, and symptom routing.
|
|
42
42
|
|
|
43
|
-
- **Read-only by design — and provable** (v1.8.0): both MCP tools are read, none write; set `VMWARE_READ_ONLY=true` (or the per-skill `VMWARE_DEBUG_READ_ONLY`) and the family read-only gate verifies that at startup instead of taking the docs' word for it — env vars are the only switch here, this skill has no config file. See [Read-Only Mode](#read-only-mode).
|
|
44
|
-
|
|
45
43
|
## MCP tools
|
|
46
44
|
|
|
47
45
|
| Tool | What |
|
|
@@ -49,44 +47,33 @@ methodology, the event-envelope contract, and symptom routing.
|
|
|
49
47
|
| `incident_timeline` | [READ] Correlate pre-fetched events → timeline + spikes + ranked hypotheses + next-check ideas |
|
|
50
48
|
| `list_symptom_categories` | [READ] List recognised symptom categories + what to check for each |
|
|
51
49
|
|
|
52
|
-
##
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
```json
|
|
68
|
-
{
|
|
69
|
-
"mcpServers": {
|
|
70
|
-
"vmware-debug": {
|
|
71
|
-
"command": "vmware-debug",
|
|
72
|
-
"args": ["mcp"],
|
|
73
|
-
"env": {
|
|
74
|
-
"VMWARE_READ_ONLY": "true"
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
50
|
+
## Offline / Air-Gapped Install (from source)
|
|
51
|
+
|
|
52
|
+
This project uses the modern PEP 517 build system (hatchling), so there is **no
|
|
53
|
+
`setup.py`** by design — that is expected, not a missing file. If you cloned the
|
|
54
|
+
source and hit `ERROR: File "setup.py" or "setup.cfg" not found ... editable mode
|
|
55
|
+
currently requires a setuptools-based build`, your `pip` is older than 21.3 and
|
|
56
|
+
cannot do an *editable* (`-e`) install with a non-setuptools backend. Editable
|
|
57
|
+
mode is a developer convenience, not needed to run the tool — do one of:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# From the source tree — a normal (non-editable) install builds a wheel:
|
|
61
|
+
pip install . # NOT pip install -e .
|
|
62
|
+
|
|
63
|
+
# ...or upgrade pip first, and editable works too:
|
|
64
|
+
pip install --upgrade pip && pip install -e .
|
|
79
65
|
```
|
|
80
66
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
67
|
+
For a **truly air-gapped host**, build the wheels on a connected machine and copy
|
|
68
|
+
them over — the target then needs no network:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
# On a connected machine, collect this package + its dependencies as wheels:
|
|
72
|
+
pip wheel . -w dist # → dist/*.whl (or: uv build, for just this package)
|
|
73
|
+
|
|
74
|
+
# Copy dist/ to the air-gapped host, then install offline:
|
|
75
|
+
pip install --no-index --find-links dist vmware-debug
|
|
76
|
+
```
|
|
90
77
|
|
|
91
78
|
## License
|
|
92
79
|
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
<!-- mcp-name: io.github.zw008/vmware-debug -->
|
|
2
|
+
|
|
3
|
+
# VMware Debug(中文)
|
|
4
|
+
|
|
5
|
+
> **声明**:本项目为社区维护的开源项目,**与 VMware, Inc. 或 Broadcom Inc. 无任何隶属、
|
|
6
|
+
> 背书或赞助关系。** "VMware"、"vSphere" 为 Broadcom 商标。源码以 MIT 许可证公开可审计。
|
|
7
|
+
|
|
8
|
+
VMware skill 家族的**诊断大脑**。你给出症状(报错、日志、变慢的 VM),它来跑系统化排查:
|
|
9
|
+
把其它 skill 取到的事件关联成一条时间线、检测突刺、给根因假设排序,并告诉你下一步该查什么。
|
|
10
|
+
**只读**——从不修改任何东西,也从不执行修复。修复一律路由给 vmware-aiops(单步)或
|
|
11
|
+
vmware-pilot(多步、带审批门控),完全复刻 vmware-harden → vmware-pilot 的「顾问/执行」分工。
|
|
12
|
+
|
|
13
|
+
## 配套 Skill
|
|
14
|
+
|
|
15
|
+
| 需求 | Skill |
|
|
16
|
+
|---|---|
|
|
17
|
+
| 故障关联 / 根因 | **vmware-debug**(本项目) |
|
|
18
|
+
| 集中日志检索 | vmware-log-insight(把 `log_search` 结果喂给它) |
|
|
19
|
+
| vCenter 事件与告警 | vmware-monitor |
|
|
20
|
+
| 指标 / 异常 | vmware-aria |
|
|
21
|
+
| 执行修复 | vmware-aiops(单步)/ vmware-pilot(多步门控) |
|
|
22
|
+
|
|
23
|
+
## 安装
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
uv tool install vmware-debug
|
|
27
|
+
vmware-debug categories # 看它能诊断哪些症状类别
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## MCP 工具(2 个,全只读)
|
|
31
|
+
|
|
32
|
+
- `incident_timeline`:把已取到的事件关联成 时间线 + 突刺 + 排序后的根因假设 + 下一步检查建议
|
|
33
|
+
- `list_symptom_categories`:症状类别及对应的排查路由(不知道查什么时用它)
|
|
34
|
+
|
|
35
|
+
**事件信封**:`{ts, source, severity, entity, text, fields}`。agent 把各源事件归一成此形状再交给
|
|
36
|
+
debug;debug 因此与其它包零运行时依赖。
|
|
37
|
+
|
|
38
|
+
## 安全
|
|
39
|
+
|
|
40
|
+
结构上只读、离线、无凭据:不连任何 vCenter/NSX/Aria,没有可破坏面,也没有秘密可泄露。
|
|
41
|
+
详见 [SECURITY.md](SECURITY.md)。
|
|
42
|
+
|
|
43
|
+
## 许可证
|
|
44
|
+
|
|
45
|
+
MIT。
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<!-- mcp-name: io.github.vmware-skills/vmware-debug -->
|
|
2
|
+
|
|
3
|
+
# VMware Debug
|
|
4
|
+
|
|
5
|
+
> ⚠️ **Work in progress** — the core (event correlation engine, MCP tools, CLI)
|
|
6
|
+
> is built and tested; README, `server.json`, full reference docs, and packaging
|
|
7
|
+
> polish are still landing. Not yet published to PyPI.
|
|
8
|
+
|
|
9
|
+
> **Disclaimer**: Community-maintained open-source project, **not affiliated with,
|
|
10
|
+
> endorsed by, or sponsored by VMware, Inc. or Broadcom Inc.** "VMware" and
|
|
11
|
+
> "vSphere" are trademarks of Broadcom. Source is publicly auditable under the MIT
|
|
12
|
+
> license.
|
|
13
|
+
|
|
14
|
+
The diagnostic brain of the VMware skill family. You bring the symptom (an error,
|
|
15
|
+
a log dump, a slow VM); this skill runs a systematic investigation, correlates
|
|
16
|
+
events from the other skills into one timeline, ranks root-cause hypotheses, and
|
|
17
|
+
tells you what to check next. It is **read-only** — it never changes anything and
|
|
18
|
+
never executes fixes. Remediation is routed to `vmware-aiops` (single op) or
|
|
19
|
+
`vmware-pilot` (multi-step, gated), mirroring the `vmware-harden → vmware-pilot`
|
|
20
|
+
advisor/executor split.
|
|
21
|
+
|
|
22
|
+
See [`skills/vmware-debug/SKILL.md`](skills/vmware-debug/SKILL.md) for the full
|
|
23
|
+
methodology, the event-envelope contract, and symptom routing.
|
|
24
|
+
|
|
25
|
+
## MCP tools
|
|
26
|
+
|
|
27
|
+
| Tool | What |
|
|
28
|
+
|---|---|
|
|
29
|
+
| `incident_timeline` | [READ] Correlate pre-fetched events → timeline + spikes + ranked hypotheses + next-check ideas |
|
|
30
|
+
| `list_symptom_categories` | [READ] List recognised symptom categories + what to check for each |
|
|
31
|
+
|
|
32
|
+
## Offline / Air-Gapped Install (from source)
|
|
33
|
+
|
|
34
|
+
This project uses the modern PEP 517 build system (hatchling), so there is **no
|
|
35
|
+
`setup.py`** by design — that is expected, not a missing file. If you cloned the
|
|
36
|
+
source and hit `ERROR: File "setup.py" or "setup.cfg" not found ... editable mode
|
|
37
|
+
currently requires a setuptools-based build`, your `pip` is older than 21.3 and
|
|
38
|
+
cannot do an *editable* (`-e`) install with a non-setuptools backend. Editable
|
|
39
|
+
mode is a developer convenience, not needed to run the tool — do one of:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
# From the source tree — a normal (non-editable) install builds a wheel:
|
|
43
|
+
pip install . # NOT pip install -e .
|
|
44
|
+
|
|
45
|
+
# ...or upgrade pip first, and editable works too:
|
|
46
|
+
pip install --upgrade pip && pip install -e .
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
For a **truly air-gapped host**, build the wheels on a connected machine and copy
|
|
50
|
+
them over — the target then needs no network:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# On a connected machine, collect this package + its dependencies as wheels:
|
|
54
|
+
pip wheel . -w dist # → dist/*.whl (or: uv build, for just this package)
|
|
55
|
+
|
|
56
|
+
# Copy dist/ to the air-gapped host, then install offline:
|
|
57
|
+
pip install --no-index --find-links dist vmware-debug
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## License
|
|
61
|
+
|
|
62
|
+
MIT.
|
|
@@ -1,3 +1,40 @@
|
|
|
1
|
+
## v1.8.8 — moved to vmware-skills org + MCP Registry namespace io.github.vmware-skills/vmware-debug
|
|
2
|
+
|
|
3
|
+
Repo transferred from github.com/zw008 to github.com/vmware-skills (redirects preserve old links).
|
|
4
|
+
MCP Registry server renamed to `io.github.vmware-skills/*`; the old `io.github.zw008/*` entry is deprecated.
|
|
5
|
+
All in-repo links updated. No functional code change on this line beyond the org move.
|
|
6
|
+
|
|
7
|
+
## v1.8.7 (2026-07-21) — the skill-level read-only switch is removed; read/write authorization is the vCenter account's job (RBAC)
|
|
8
|
+
|
|
9
|
+
### Removed: `VMWARE_READ_ONLY` / `read_only:` — give the agent a read-only service account instead
|
|
10
|
+
|
|
11
|
+
The skill-level read-only switch is gone. It was enforced only on the MCP tool
|
|
12
|
+
registry, and any agent with a shell (every SKILL.md grants `allowed-tools: Bash`)
|
|
13
|
+
could reach the same change one CLI command away — so it withheld the *tool*, not
|
|
14
|
+
the *capability*. It was never a real boundary.
|
|
15
|
+
|
|
16
|
+
To run an agent read-only, give it a **read-only vCenter/NSX service account
|
|
17
|
+
(RBAC)**. Writes are then refused at the platform, un-bypassably, regardless of
|
|
18
|
+
surface or shell — the one place read/write control cannot be stepped around. A
|
|
19
|
+
config still carrying `read_only: true` is ignored, with a one-time warning that
|
|
20
|
+
names the replacement (no silent behavior change).
|
|
21
|
+
|
|
22
|
+
### Removed: approval tiers and the declared-environment gate (via vmware-policy)
|
|
23
|
+
|
|
24
|
+
The graduated-autonomy approval tiers (`confirm`/`dual`/`review`) and the "declare
|
|
25
|
+
an environment or be refused" baseline are removed — they only ever fired on the
|
|
26
|
+
rarest configuration while carrying the family's most complex machinery. Opt-in
|
|
27
|
+
`deny` rules and the maintenance window remain, and apply identically wherever a
|
|
28
|
+
tool runs.
|
|
29
|
+
|
|
30
|
+
### Added: offline / air-gapped install docs
|
|
31
|
+
|
|
32
|
+
The README now covers installing from source without editable mode (for older
|
|
33
|
+
`pip`) and building wheels to carry onto an air-gapped host — the modern PEP 517
|
|
34
|
+
layout has no `setup.py` by design, which is expected, not a missing file.
|
|
35
|
+
|
|
36
|
+
This release also carries the accumulated fixes staged since 1.8.5.
|
|
37
|
+
|
|
1
38
|
## v1.8.5 (2026-07-20) — the two fixes v1.8.4 announced now actually work
|
|
2
39
|
|
|
3
40
|
Four adversarial reviews of v1.8.4 found that both of its headline fixes were
|
|
@@ -224,7 +261,7 @@ this package has no config file.
|
|
|
224
261
|
|
|
225
262
|
## v1.8.0 (2026-07-18) — read-only mode, working policy defaults, declared environments
|
|
226
263
|
|
|
227
|
-
Family release driven by [VMware-AIops#31](https://github.com/
|
|
264
|
+
Family release driven by [VMware-AIops#31](https://github.com/vmware-skills/VMware-AIops/issues/31),
|
|
228
265
|
where an operator running Llama 3.3 70B (Goose / OpenShift AI, on-prem H100) had to
|
|
229
266
|
hand-write 17 prompt guardrails to make tool calling reliable. A prompt is advisory — a
|
|
230
267
|
model can ignore it. Every guardrail that could move into the harness has.
|
|
@@ -311,4 +348,4 @@ executes fixes (advisor/executor split, mirroring vmware-harden → vmware-pilot
|
|
|
311
348
|
### Notes
|
|
312
349
|
- Read-only by construction; remediation is routed, never executed.
|
|
313
350
|
- `parse_timestamp` rejects implausible/garbage timestamps loudly rather than
|
|
314
|
-
silently landing at the epoch.
|
|
351
|
+
silently landing at the epoch.
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
This is a community-maintained open-source project and is **not affiliated with,
|
|
6
6
|
endorsed by, or sponsored by VMware, Inc. or Broadcom Inc.** "VMware" and
|
|
7
7
|
"vSphere" are trademarks of Broadcom. Source code is publicly auditable at
|
|
8
|
-
[github.com/
|
|
8
|
+
[github.com/vmware-skills/VMware-Debug](https://github.com/vmware-skills/VMware-Debug) under the
|
|
9
9
|
MIT license.
|
|
10
10
|
|
|
11
11
|
## Reporting Vulnerabilities
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vmware-debug"
|
|
7
|
-
version = "1.8.
|
|
7
|
+
version = "1.8.8"
|
|
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"
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
|
-
"name": "io.github.
|
|
3
|
+
"name": "io.github.vmware-skills/vmware-debug",
|
|
4
4
|
"title": "VMware Debug",
|
|
5
5
|
"description": "Read-only VMware incident correlation: timeline, spikes, root-cause routing. 2 MCP tools.",
|
|
6
6
|
"repository": {
|
|
7
|
-
"url": "https://github.com/
|
|
7
|
+
"url": "https://github.com/vmware-skills/VMware-Debug",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.8.
|
|
10
|
+
"version": "1.8.8",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "vmware-debug",
|
|
15
|
-
"version": "1.8.
|
|
15
|
+
"version": "1.8.8",
|
|
16
16
|
"transport": {
|
|
17
17
|
"type": "stdio"
|
|
18
18
|
}
|
|
@@ -19,7 +19,7 @@ installer:
|
|
|
19
19
|
package: vmware-debug
|
|
20
20
|
allowed-tools:
|
|
21
21
|
- Bash
|
|
22
|
-
metadata: {"openclaw":{"requires":{"bins":["vmware-debug"]},"optional":{"env":["
|
|
22
|
+
metadata: {"openclaw":{"requires":{"bins":["vmware-debug"]},"optional":{"env":["VMWARE_AUDIT_APPROVED_BY","VMWARE_AUDIT_RATIONALE"],"bins":["vmware-policy"]},"primaryEnv":"NONE","homepage":"https://github.com/vmware-skills/VMware-Debug","os":["macos","linux"]}}
|
|
23
23
|
---
|
|
24
24
|
|
|
25
25
|
# VMware Debug
|
|
@@ -113,17 +113,11 @@ a recommended plan.
|
|
|
113
113
|
See `references/event-envelope.md`. The agent normalises each source's events into this
|
|
114
114
|
shape; debug stays source-agnostic and has no dependency on the other packages.
|
|
115
115
|
|
|
116
|
-
## Read-Only
|
|
117
|
-
|
|
118
|
-
Both tools here are reads,
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
document's word for it. Debug has no config file, so the env vars are the only switch. The
|
|
122
|
-
same family variable withholds write tools across every companion skill, so a whole-estate
|
|
123
|
-
audit posture is one setting — and when you route a fix to vmware-aiops or vmware-pilot and
|
|
124
|
-
the tool is missing from *their* `list_tools()`, that is the lockdown, not a fault. Do not
|
|
125
|
-
retry or hunt for another route: name the blocked operation and say an operator must clear
|
|
126
|
-
the switch and restart that server. Running with local or small models? See [`references/agent-guardrails.md`](references/agent-guardrails.md).
|
|
116
|
+
## Read-Only by Design
|
|
117
|
+
|
|
118
|
+
Both tools here are reads — zero write tools, zero network access of its own.
|
|
119
|
+
Running with local or small models? See
|
|
120
|
+
[`references/agent-guardrails.md`](references/agent-guardrails.md).
|
|
127
121
|
|
|
128
122
|
## CLI Quick Reference
|
|
129
123
|
|
{vmware_debug-1.8.5 → vmware_debug-1.8.8}/skills/vmware-debug/references/agent-guardrails.md
RENAMED
|
@@ -10,7 +10,7 @@ guardrails below are adapted, with thanks, from the working configuration
|
|
|
10
10
|
[@juanpf-ha](https://github.com/juanpf-ha) developed while running
|
|
11
11
|
vmware-monitor and vmware-aria against a production vSphere estate with Llama
|
|
12
12
|
3.3 70B FP8 on an on-prem H100
|
|
13
|
-
([VMware-AIops#31](https://github.com/
|
|
13
|
+
([VMware-AIops#31](https://github.com/vmware-skills/VMware-AIops/issues/31)). The
|
|
14
14
|
cross-skill rules are identical across this family; the parts below marked
|
|
15
15
|
vmware-debug are specific to this skill.
|
|
16
16
|
|
|
@@ -34,50 +34,13 @@ These are structural, so it cannot.
|
|
|
34
34
|
|
|
35
35
|
| Guardrail you would otherwise prompt for | Now enforced by |
|
|
36
36
|
|---|---|
|
|
37
|
-
| "Work
|
|
37
|
+
| "Work read-only and never modify anything" | **The tool surface itself.** Both tools are reads — this skill has no write tool at all, so there is nothing to withhold and nothing to switch off. |
|
|
38
38
|
| "Diagnose only — never apply the fix you propose" | **Structural.** This skill has no tool that changes anything, and it holds no connection to vCenter, NSX or anything else. Remediation is routed to vmware-aiops or vmware-pilot by the calling agent. |
|
|
39
39
|
| "Do not fabricate a timeline — build it from the events I gave you" | **`incident_timeline` correlates only its input.** It is source-agnostic and has no way to fetch anything, so the timeline cannot contain an event the agent did not supply. |
|
|
40
40
|
| "Tell me when the symptom is outside what you can recognise" | **`list_symptom_categories`** states the catalogue, and unmatched symptoms come back as `uncategorized` rather than being forced into the nearest signature. |
|
|
41
41
|
| "Use explicit limits for queries that may return large amounts of data" | **The list envelope.** `list_symptom_categories` returns `{items, returned, limit, total, truncated, hint}` with `truncated` always `false` — which is the point: it states that the catalogue is complete instead of leaving you to infer it. |
|
|
42
42
|
| "Log everything you looked at" | **The `@vmware_tool` decorator.** Every call is recorded to `~/.vmware/audit.db`, reads included. |
|
|
43
43
|
|
|
44
|
-
### Turning read-only mode on
|
|
45
|
-
|
|
46
|
-
One variable covers every skill in the family:
|
|
47
|
-
|
|
48
|
-
```json
|
|
49
|
-
{
|
|
50
|
-
"mcpServers": {
|
|
51
|
-
"vmware-debug": {
|
|
52
|
-
"command": "vmware-debug",
|
|
53
|
-
"args": ["mcp"],
|
|
54
|
-
"env": { "VMWARE_READ_ONLY": "true" }
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
Per-skill override:
|
|
61
|
-
|
|
62
|
-
```bash
|
|
63
|
-
VMWARE_READ_ONLY=true # whole family read-only
|
|
64
|
-
VMWARE_DEBUG_READ_ONLY=false # …except this skill
|
|
65
|
-
```
|
|
66
|
-
|
|
67
|
-
**This skill has no `config.yaml`**, so the two environment variables are the
|
|
68
|
-
only switch — there is no `read_only:` configuration setting to fall back on.
|
|
69
|
-
Precedence is per-skill env → family env → off. An unparseable value
|
|
70
|
-
(`VMWARE_READ_ONLY=ture`) enables read-only mode rather than silently ignoring
|
|
71
|
-
the typo.
|
|
72
|
-
|
|
73
|
-
Setting it here is worth doing even though nothing is withheld: the same
|
|
74
|
-
variable withholds write tools across every companion skill, so a whole-estate
|
|
75
|
-
diagnostic posture is one setting. That matters especially in this skill's
|
|
76
|
-
workflow — you gather signals read-only, correlate, and then route a fix. When
|
|
77
|
-
the fix tool is missing from vmware-aiops's or vmware-pilot's `list_tools()`,
|
|
78
|
-
that is the lockdown working, not a fault: name the blocked operation and stop,
|
|
79
|
-
rather than retrying or hunting for another route.
|
|
80
|
-
|
|
81
44
|
---
|
|
82
45
|
|
|
83
46
|
## The system prompt
|
|
@@ -168,4 +131,4 @@ Local-model compatibility is an explicit design constraint for this family, and
|
|
|
168
131
|
the evidence base is small. If you evaluate a model against this skill —
|
|
169
132
|
Qwen, Mistral, Granite, or anything else — a report of what worked and what did
|
|
170
133
|
not is genuinely useful:
|
|
171
|
-
[github.com/
|
|
134
|
+
[github.com/vmware-skills/VMware-Debug/issues](https://github.com/vmware-skills/VMware-Debug/issues).
|
|
@@ -7,11 +7,6 @@ Read-only, offline incident correlation. No network, no credentials, no writes.
|
|
|
7
7
|
| `incident_timeline` | `{event_count, window, spikes:[{start,end,count,zscore}], hypotheses:[{category, score, summary, evidence_count, first_seen, last_seen, sample_text, suggested_check}], next_checks:[...]}` | 300–2000 (scales with hypotheses) |
|
|
8
8
|
| `list_symptom_categories` | `{items: [{category, example_keywords, suggested_check}], returned, limit, total, truncated, hint}` | ~400 |
|
|
9
9
|
|
|
10
|
-
> Read-only mode (`VMWARE_DEBUG_READ_ONLY=true` or the family-wide `VMWARE_READ_ONLY=true`;
|
|
11
|
-
> debug has no config file) removes nothing from this table — both tools are `[READ]`, and
|
|
12
|
-
> the gate proves that at start-up rather than trusting the marker. Classification comes
|
|
13
|
-
> from the `[READ]`/`[WRITE]` docstring marker — see README.
|
|
14
|
-
|
|
15
10
|
`list_symptom_categories` returns the family list envelope — read the rows from
|
|
16
11
|
`items`. It has no `limit` parameter, which is exactly why the envelope matters:
|
|
17
12
|
`truncated: false` states that this is every category there is, rather than
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# vmware-debug Setup Guide
|
|
2
|
+
|
|
3
|
+
vmware-debug has **no configuration, no credentials, and no network access** — it
|
|
4
|
+
is a pure, offline correlation engine. There is no `config.yaml` and no `.env`.
|
|
5
|
+
|
|
6
|
+
## Install
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
uv tool install vmware-debug
|
|
10
|
+
vmware-debug categories # verify it runs
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## MCP client configuration
|
|
14
|
+
|
|
15
|
+
```json
|
|
16
|
+
{
|
|
17
|
+
"command": "uvx",
|
|
18
|
+
"args": ["--from", "vmware-debug", "vmware-debug-mcp"]
|
|
19
|
+
}
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
If installed with `uv tool install`, prefer the entry point `vmware-debug mcp`
|
|
23
|
+
(no PyPI resolution at startup — robust behind corporate TLS proxies, 踩坑 #25).
|
|
24
|
+
|
|
25
|
+
For full cross-skill diagnosis, also install the data-source skills it correlates
|
|
26
|
+
(vmware-monitor, vmware-log-insight, vmware-aria, vmware-nsx) and the executors it
|
|
27
|
+
routes fixes to (vmware-aiops, vmware-pilot).
|
|
28
|
+
|
|
29
|
+
## Security
|
|
30
|
+
|
|
31
|
+
> **Disclaimer**: Community-maintained open-source project, **not affiliated with,
|
|
32
|
+
> endorsed by, or sponsored by VMware, Inc. or Broadcom Inc.**
|
|
33
|
+
|
|
34
|
+
1. **Source Code** — https://github.com/vmware-skills/VMware-Debug (MIT).
|
|
35
|
+
2. **Credentials** — none. debug holds no secrets and connects to nothing.
|
|
36
|
+
3. **Network** — none. All tools are local pure functions over event data the
|
|
37
|
+
agent supplies.
|
|
38
|
+
4. **Writes** — none. debug only diagnoses and recommends; remediation is routed
|
|
39
|
+
to vmware-aiops / vmware-pilot, where confirmation/approval/audit live.
|
|
40
|
+
5. **No cross-skill coupling** — events arrive as plain dicts (the event
|
|
41
|
+
envelope); debug imports no other skill package at runtime.
|
|
42
|
+
6. **Environment scoping** — policy rules can scope by environment, and skills
|
|
43
|
+
that connect to a VMware estate may declare `environment:` (`production` /
|
|
44
|
+
`staging` / `lab`) per target in their own `config.yaml` as an optional label
|
|
45
|
+
an environment-scoped `deny` rule can match on. debug has no config and no
|
|
46
|
+
connection to declare one about, so it reports a constant `local`. Since it
|
|
47
|
+
ships no operation above read risk, nothing here is gated either way.
|
|
48
|
+
7. **Static analysis** — `uvx bandit -r vmware_debug/` (release bar:
|
|
49
|
+
0 Medium+).
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
},
|
|
35
35
|
"maximum": 1,
|
|
36
36
|
"pct": 100.0,
|
|
37
|
+
"stale": true,
|
|
37
38
|
"unit": "required entity params",
|
|
38
39
|
"value": 1
|
|
39
40
|
},
|
|
40
41
|
"entry_point_availability": {
|
|
41
42
|
"detail": {
|
|
42
|
-
"full_entry_points": 2
|
|
43
|
-
"read_only_entry_points": 2
|
|
43
|
+
"full_entry_points": 2
|
|
44
44
|
},
|
|
45
45
|
"maximum": 2,
|
|
46
46
|
"pct": 100.0,
|
|
@@ -53,16 +53,16 @@
|
|
|
53
53
|
"dead_end_count": 0,
|
|
54
54
|
"dead_end_errors": [],
|
|
55
55
|
"per_dimension_pct": {
|
|
56
|
-
"names_artifact":
|
|
56
|
+
"names_artifact": 87.5,
|
|
57
57
|
"names_input": 100.0,
|
|
58
58
|
"states_remedy": 100.0
|
|
59
59
|
},
|
|
60
|
-
"raise_sites":
|
|
60
|
+
"raise_sites": 8
|
|
61
61
|
},
|
|
62
|
-
"maximum":
|
|
63
|
-
"pct":
|
|
62
|
+
"maximum": 24,
|
|
63
|
+
"pct": 95.8,
|
|
64
64
|
"unit": "points",
|
|
65
|
-
"value":
|
|
65
|
+
"value": 23
|
|
66
66
|
},
|
|
67
67
|
"manifest_context_headroom": {
|
|
68
68
|
"detail": {
|
|
@@ -109,6 +109,7 @@
|
|
|
109
109
|
},
|
|
110
110
|
"maximum": 450,
|
|
111
111
|
"pct": 0.0,
|
|
112
|
+
"stale": true,
|
|
112
113
|
"unit": "tokens",
|
|
113
114
|
"value": 0
|
|
114
115
|
},
|
|
@@ -126,23 +127,20 @@
|
|
|
126
127
|
"budget_chars": 500,
|
|
127
128
|
"over_budget": [],
|
|
128
129
|
"remedy_after_interpolation": [
|
|
129
|
-
"envelope.py:
|
|
130
|
-
"envelope.py:
|
|
131
|
-
"envelope.py:160",
|
|
132
|
-
"envelope.py:107",
|
|
133
|
-
"envelope.py:200",
|
|
130
|
+
"envelope.py:126",
|
|
131
|
+
"envelope.py:138",
|
|
134
132
|
"timeline.py:119"
|
|
135
133
|
]
|
|
136
134
|
},
|
|
137
|
-
"maximum":
|
|
135
|
+
"maximum": 8,
|
|
138
136
|
"pct": 100.0,
|
|
139
137
|
"unit": "messages",
|
|
140
|
-
"value":
|
|
138
|
+
"value": 8
|
|
141
139
|
},
|
|
142
140
|
"teaching_error_rate": {
|
|
143
141
|
"detail": {},
|
|
144
|
-
"maximum":
|
|
145
|
-
"pct":
|
|
142
|
+
"maximum": 8,
|
|
143
|
+
"pct": 87.5,
|
|
146
144
|
"unit": "messages",
|
|
147
145
|
"value": 7
|
|
148
146
|
},
|
|
@@ -11,7 +11,6 @@ from __future__ import annotations
|
|
|
11
11
|
|
|
12
12
|
import asyncio
|
|
13
13
|
import importlib
|
|
14
|
-
import os
|
|
15
14
|
import sys
|
|
16
15
|
from typing import Any
|
|
17
16
|
|
|
@@ -20,36 +19,26 @@ import pytest
|
|
|
20
19
|
from ._scoring import ScoreBoard
|
|
21
20
|
from ._skill import SERVER_MODULE, get_server
|
|
22
21
|
|
|
23
|
-
#: Prefix of the modules
|
|
22
|
+
#: Prefix of the server modules re-imported by ``load_tools``.
|
|
24
23
|
_SERVER_PREFIX = SERVER_MODULE.split(".")[0] + ".mcp_server"
|
|
25
24
|
|
|
26
|
-
_READ_ONLY_ENV = "VMWARE_READ_ONLY"
|
|
27
|
-
|
|
28
25
|
|
|
29
26
|
def load_tools(read_only: bool = False) -> tuple[Any, ...]:
|
|
30
27
|
"""Import the MCP server fresh and return the tools it registers.
|
|
31
28
|
|
|
32
|
-
Re-imports rather than reusing the loaded module because the
|
|
33
|
-
|
|
34
|
-
deleting them would leave other test files
|
|
35
|
-
imports any more, and their patches would
|
|
29
|
+
Re-imports rather than reusing the loaded module because the tools register
|
|
30
|
+
themselves onto the registry at import time. The original module objects are
|
|
31
|
+
restored afterwards — deleting them would leave other test files
|
|
32
|
+
monkeypatching a module nobody imports any more, and their patches would
|
|
33
|
+
silently stop applying.
|
|
36
34
|
"""
|
|
37
35
|
saved = {n: m for n, m in sys.modules.items() if n.startswith(_SERVER_PREFIX)}
|
|
38
|
-
prior = os.environ.get(_READ_ONLY_ENV)
|
|
39
36
|
try:
|
|
40
|
-
if read_only:
|
|
41
|
-
os.environ[_READ_ONLY_ENV] = "true"
|
|
42
|
-
else:
|
|
43
|
-
os.environ.pop(_READ_ONLY_ENV, None)
|
|
44
37
|
for name in list(saved):
|
|
45
38
|
del sys.modules[name]
|
|
46
39
|
mod = importlib.import_module(SERVER_MODULE)
|
|
47
40
|
return tuple(asyncio.run(get_server(mod).list_tools()))
|
|
48
41
|
finally:
|
|
49
|
-
if prior is None:
|
|
50
|
-
os.environ.pop(_READ_ONLY_ENV, None)
|
|
51
|
-
else:
|
|
52
|
-
os.environ[_READ_ONLY_ENV] = prior
|
|
53
42
|
for name in [n for n in sys.modules if n.startswith(_SERVER_PREFIX)]:
|
|
54
43
|
del sys.modules[name]
|
|
55
44
|
sys.modules.update(saved)
|
|
@@ -72,9 +61,3 @@ def tools() -> tuple[Any, ...]:
|
|
|
72
61
|
model's context, not the docstring as written.
|
|
73
62
|
"""
|
|
74
63
|
return load_tools(read_only=False)
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
@pytest.fixture(scope="session")
|
|
78
|
-
def gated_tools() -> tuple[Any, ...]:
|
|
79
|
-
"""The surface an operator gets under ``VMWARE_READ_ONLY=true``."""
|
|
80
|
-
return load_tools(read_only=True)
|