vmware-debug 1.8.7__tar.gz → 1.8.9__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.9/.claude-plugin/plugin.json +21 -0
- vmware_debug-1.8.9/.mcp.json +13 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/PKG-INFO +7 -3
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/README-CN.md +1 -1
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/README.md +1 -1
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/RELEASE_NOTES.md +27 -2
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/SECURITY.md +1 -1
- vmware_debug-1.8.9/docs/plans/2026-08-28-investigation-layer-design.md +120 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/pyproject.toml +8 -1
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/server.json +4 -4
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/skills/vmware-debug/SKILL.md +1 -1
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/skills/vmware-debug/references/agent-guardrails.md +2 -2
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/skills/vmware-debug/references/setup-guide.md +1 -1
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/uv.lock +51 -51
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/__init__.py +1 -1
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/mcp_server/server.py +6 -0
- vmware_debug-1.8.7/tests/eval/regression/test_declared_environment.py +0 -181
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/.gitignore +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/skills/vmware-debug/references/capabilities.md +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/skills/vmware-debug/references/cli-reference.md +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/skills/vmware-debug/references/event-envelope.md +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/skills/vmware-debug/references/routing.md +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/__init__.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/__init__.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/_family.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/_scores.json +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/_scoring.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/_skill.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/conftest.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/test_entity_reachability.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/test_error_actionability.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/test_tool_description_quality.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/test_tool_manifest_budget.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/regression/__init__.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/regression/test_capability_grader.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/regression/test_debug_regressions.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/regression/test_result_envelope.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/regression/test_tool_annotations.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/test_safe_error_passthrough.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/test_timeline.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/cli.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/envelope.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/mcp/__init__.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/mcp/tools.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/mcp_server/__init__.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/ops/__init__.py +0 -0
- {vmware_debug-1.8.7 → vmware_debug-1.8.9}/vmware_debug/ops/timeline.py +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://anthropic.com/claude-code/plugin.schema.json",
|
|
3
|
+
"name": "vmware-debug",
|
|
4
|
+
"displayName": "VMware Debug",
|
|
5
|
+
"version": "1.8.9",
|
|
6
|
+
"description": "Read-only VMware incident correlation: timeline, spikes, root-cause routing. 2 MCP tools.",
|
|
7
|
+
"author": {
|
|
8
|
+
"name": "Wei Zhou",
|
|
9
|
+
"email": "zhouwei008@gmail.com",
|
|
10
|
+
"url": "https://github.com/vmware-skills"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/vmware-skills/VMware-Debug",
|
|
13
|
+
"repository": "https://github.com/vmware-skills/VMware-Debug",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"keywords": [
|
|
16
|
+
"debug",
|
|
17
|
+
"mcp",
|
|
18
|
+
"vmware",
|
|
19
|
+
"vsphere"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: vmware-debug
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.9
|
|
4
4
|
Summary: VMware diagnostic brain — read-only incident triage, log/event correlation, and root-cause routing across the VMware skill family
|
|
5
|
+
Project-URL: Homepage, https://github.com/vmware-skills/VMware-Debug
|
|
6
|
+
Project-URL: Repository, https://github.com/vmware-skills/VMware-Debug
|
|
7
|
+
Project-URL: Issues, https://github.com/vmware-skills/VMware-Debug/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/vmware-skills/VMware-Debug/blob/main/RELEASE_NOTES.md
|
|
5
9
|
Author-email: Wei Zhou <wei-wz.zhou@broadcom.com>
|
|
6
10
|
License-Expression: MIT
|
|
7
11
|
Keywords: ai-ops,debug,diagnostics,mcp,rca,troubleshooting,vmware,vsphere
|
|
@@ -16,7 +20,7 @@ Requires-Dist: typer<1.0,>=0.12
|
|
|
16
20
|
Requires-Dist: vmware-policy<2.0,>=1.8.5
|
|
17
21
|
Description-Content-Type: text/markdown
|
|
18
22
|
|
|
19
|
-
<!-- mcp-name: io.github.
|
|
23
|
+
<!-- mcp-name: io.github.vmware-skills/vmware-debug -->
|
|
20
24
|
|
|
21
25
|
# VMware Debug
|
|
22
26
|
|
|
@@ -1,3 +1,28 @@
|
|
|
1
|
+
## v1.8.9 — two wrong numbers: the server's own version, and the advertised tool count
|
|
2
|
+
|
|
3
|
+
Both defects were invisible to the test suites and both were user-facing.
|
|
4
|
+
|
|
5
|
+
- **The MCP server reported the SDK's version as its own.** `FastMCP` accepts no
|
|
6
|
+
`version` argument and leaves the lowlevel server's at `None`; with it `None`
|
|
7
|
+
the SDK answers `initialize` with its OWN version. Every skill in the family
|
|
8
|
+
therefore told its client it was mcp 1.29.1 — a number that exists for no
|
|
9
|
+
package here, and one that would change with an SDK bump and no code change of
|
|
10
|
+
ours. Verified end to end rather than by reading: unset the field and a probe
|
|
11
|
+
server reports the installed SDK's version; set it and it reports ours.
|
|
12
|
+
|
|
13
|
+
Also new: this repo is installable as a Claude Code plugin
|
|
14
|
+
(`/plugin install vmware-debug@vmware-skills`). The skill and its MCP server arrive in
|
|
15
|
+
one step; nothing is duplicated, the manifest points at the existing `skills/`
|
|
16
|
+
tree. family_smoke gained three gates — the server's reported version, the plugin
|
|
17
|
+
manifest's agreement with pyproject, and the advertised tool count against the
|
|
18
|
+
live registration.
|
|
19
|
+
|
|
20
|
+
## v1.8.8 — moved to vmware-skills org + MCP Registry namespace io.github.vmware-skills/vmware-debug
|
|
21
|
+
|
|
22
|
+
Repo transferred from github.com/zw008 to github.com/vmware-skills (redirects preserve old links).
|
|
23
|
+
MCP Registry server renamed to `io.github.vmware-skills/*`; the old `io.github.zw008/*` entry is deprecated.
|
|
24
|
+
All in-repo links updated. No functional code change on this line beyond the org move.
|
|
25
|
+
|
|
1
26
|
## v1.8.7 (2026-07-21) — the skill-level read-only switch is removed; read/write authorization is the vCenter account's job (RBAC)
|
|
2
27
|
|
|
3
28
|
### Removed: `VMWARE_READ_ONLY` / `read_only:` — give the agent a read-only service account instead
|
|
@@ -255,7 +280,7 @@ this package has no config file.
|
|
|
255
280
|
|
|
256
281
|
## v1.8.0 (2026-07-18) — read-only mode, working policy defaults, declared environments
|
|
257
282
|
|
|
258
|
-
Family release driven by [VMware-AIops#31](https://github.com/
|
|
283
|
+
Family release driven by [VMware-AIops#31](https://github.com/vmware-skills/VMware-AIops/issues/31),
|
|
259
284
|
where an operator running Llama 3.3 70B (Goose / OpenShift AI, on-prem H100) had to
|
|
260
285
|
hand-write 17 prompt guardrails to make tool calling reliable. A prompt is advisory — a
|
|
261
286
|
model can ignore it. Every guardrail that could move into the harness has.
|
|
@@ -342,4 +367,4 @@ executes fixes (advisor/executor split, mirroring vmware-harden → vmware-pilot
|
|
|
342
367
|
### Notes
|
|
343
368
|
- Read-only by construction; remediation is routed, never executed.
|
|
344
369
|
- `parse_timestamp` rejects implausible/garbage timestamps loudly rather than
|
|
345
|
-
silently landing at the epoch.
|
|
370
|
+
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
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# vmware-debug 调查层设计(MetaRAG 方法论落地)
|
|
2
|
+
|
|
3
|
+
> 状态:**设计中**,已验证第 1–2 段,第 3 段起未定。代码未动。
|
|
4
|
+
> 来源:《AI 辅助日志分析 · 鹏鼎 VMware 技术交流日》(2026-08)第 4 / 6 / 11 / 12 / 13 页。
|
|
5
|
+
|
|
6
|
+
## 一句话
|
|
7
|
+
|
|
8
|
+
把六级价值阶梯里家族最空的三级——**判、行、学**——做成 `vmware-debug` 的能力:
|
|
9
|
+
它是调查的**账本和裁判**,不是取证的手。
|
|
10
|
+
|
|
11
|
+
## 为什么落在 debug,而不是新建 skill
|
|
12
|
+
|
|
13
|
+
八步证据闭环里有六步是**跨 skill 的状态**(事件范围、Evidence ID、假设账本、
|
|
14
|
+
时间线、知识约束、结论等级)。塞进任何一个数据源 skill 都会变形;新建第 16 个
|
|
15
|
+
skill 又会把家族的入口再切一刀。debug 已经被定义为「诊断大脑」,且今天只有
|
|
16
|
+
2 个工具、914 行——它的问题不是位置不对,是**没有状态**。
|
|
17
|
+
|
|
18
|
+
## 已定的三个决定
|
|
19
|
+
|
|
20
|
+
### D1 载体:vmware-debug,不新建 skill
|
|
21
|
+
产品形态按 **B 起步、留 C 的接口**:B = 调度现有 skill 的调查层;
|
|
22
|
+
C = 面向客户的引导壳("你的日志在哪、设备怎么连、知识库挂什么"),
|
|
23
|
+
作为 debug 之上的一层引导,不做成独立产品形态。
|
|
24
|
+
|
|
25
|
+
### D2 状态:case 目录为主,SQLite 只做索引
|
|
26
|
+
```
|
|
27
|
+
~/.vmware/cases/<case-id>/ # OPS_HOME 可重定向到共享盘 / 工单系统挂载点
|
|
28
|
+
├── scope.json 对象·版本·时间窗·范围,以及它是怎么被确定的
|
|
29
|
+
├── plan.jsonl 每条取证指令:skill·工具·参数·目的·状态
|
|
30
|
+
├── evidence/ 每条证据一个 Evidence ID:来源·原始查询·取回时间
|
|
31
|
+
├── gaps.json 该取没取到的:原因·影响哪个假设·怎么补
|
|
32
|
+
├── timeline.md Trigger · Symptom · Propagation · Recovery
|
|
33
|
+
├── hypotheses.md 假设账本:支持证据 · 反证 · 缺口 · 下一步
|
|
34
|
+
├── conclusion.md 分级结论 + 升级依据 + 未验证项
|
|
35
|
+
└── case.json 索引摘要(同步写入 investigation.db)
|
|
36
|
+
```
|
|
37
|
+
除 `case.json` 外**全部人可读文本**。这个目录本身就是交付物(PPT 第 3 页的
|
|
38
|
+
"证据包"):客户整包拿走、自己翻、自己审结论怎么来的;也能在**没有任何 VMware
|
|
39
|
+
环境**的机器上用 debug 重新审阅——这是 D3 保住零凭据换来的能力。
|
|
40
|
+
|
|
41
|
+
索引与目录将来可统一,先不合并。
|
|
42
|
+
|
|
43
|
+
### D3 证据流:Agent 编排,debug 永不持凭据
|
|
44
|
+
debug 输出**结构化取证指令**,模型去调 Monitor / Aria / Log-Insight / NSX 等,
|
|
45
|
+
把结果交回 debug 入库校验。debug 对 VMware 环境保持零连接、零凭据。
|
|
46
|
+
|
|
47
|
+
前提条件——**证据契约要硬**:
|
|
48
|
+
- `case_plan` 输出可执行结构(skill·tool·params·purpose·blocks_hypothesis),
|
|
49
|
+
不是散文提示。散文会被模型自由发挥,结构化指令不会。
|
|
50
|
+
- `case_submit_evidence` 收证时做第 03 步校验:时间戳归一、时钟偏差检测、实体对齐;
|
|
51
|
+
**取不到的显式记 gap,绝不当作"没问题"**。
|
|
52
|
+
|
|
53
|
+
最后这条是 harden v1.10.0「采集器跑了 ≠ 这台主机被判定了」的同构——
|
|
54
|
+
合规域已经把这个纪律写对过一遍,调查域是复用,不是新发明。
|
|
55
|
+
参见家族 CLAUDE.md 反复出现的错误形态 #1:空结果读作「没问题」。
|
|
56
|
+
|
|
57
|
+
## 调查状态机(对应 PPT 第 6 页八步)
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
open → 01 定义事件 → scope.json
|
|
61
|
+
collecting → 02/03 取证 + 规范校验 → evidence/ + gaps.json
|
|
62
|
+
analyzing → 04/05 压缩排序 + 时间线 → timeline.md
|
|
63
|
+
hypothesis → 06 假设账本 → hypotheses.md
|
|
64
|
+
grading → 07/08 知识校验 + 分级 → conclusion.md
|
|
65
|
+
closed → 归档 + 索引 + 沉淀
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 工具面(9 新 + 2 保留 = 11)
|
|
69
|
+
|
|
70
|
+
| 工具 | 读写 | 作用 |
|
|
71
|
+
|---|:--:|---|
|
|
72
|
+
| `case_open` | W | 定义事件 → case_id + 第一批取证清单 |
|
|
73
|
+
| `case_plan` | R | 下一步该取什么(随假设状态变化,非静态清单)|
|
|
74
|
+
| `case_submit_evidence` | W | 收证 + 规范校验 + 落 gap |
|
|
75
|
+
| `case_timeline` | R | 压缩排序 + Trigger/Symptom/Propagation/Recovery |
|
|
76
|
+
| `case_hypotheses` | R | 假设账本当前状态 |
|
|
77
|
+
| `case_grade` | W | 结论分级,**升级规则不满足即拒绝升级** |
|
|
78
|
+
| `case_close` | W | 归档 + 写索引 + 沉淀为案例 |
|
|
79
|
+
| `case_list` / `case_get` | R | 跨案例检索,支撑「学」与 Eval |
|
|
80
|
+
| `incident_timeline` | R | 保留:无 case 的一次性用法 |
|
|
81
|
+
| `list_symptom_categories` | R | 保留 |
|
|
82
|
+
|
|
83
|
+
发版前必须过 `tests/eval/capability/test_tool_manifest_budget.py`。
|
|
84
|
+
|
|
85
|
+
### 证据源目录(第 11 页「日志源智能路由」)
|
|
86
|
+
什么对象 × 什么故障类型 → 该调哪个 skill 的哪个工具。
|
|
87
|
+
**必须是数据文件,不能写死在 prompt 里**,并接上 `family_smoke` 既有的
|
|
88
|
+
「文档里每个工具名都必须真实存在于家族 MCP registry」检查,杜绝幽灵工具。
|
|
89
|
+
|
|
90
|
+
### READ-ONLY 口径修正
|
|
91
|
+
现在 SKILL.md 写「READ-ONLY: it never changes anything」。加了 case 之后:
|
|
92
|
+
- 对 **VMware 环境**仍是零写入——这个承诺不变,是 debug 的卖点
|
|
93
|
+
- 对**本地 case 状态**是写:四个 W 工具照家族规矩挂 `@vmware_tool` 审计
|
|
94
|
+
|
|
95
|
+
措辞要改准,不能含糊过去。**但要等工具真的存在之后再改**——
|
|
96
|
+
今天 debug 确实什么都不写,提前改反而是另一个方向的假话。
|
|
97
|
+
|
|
98
|
+
## 未定(待续的设计段落)
|
|
99
|
+
|
|
100
|
+
- **第 3 段 结论治理**:Candidate / Probable / Confirmed / Excluded 的**升级规则**。
|
|
101
|
+
PPT 第 13 页的硬约束:"没有直接硬件诊断时停留在 Candidate 或 Probable"。
|
|
102
|
+
规则写在哪、谁执行、怎么防止模型自行升级。
|
|
103
|
+
- **第 4 段 知识层**:KB / Runbook / 历史案例怎么挂载;第 07 步「版本约束」
|
|
104
|
+
(产品·Build·驱动·固件的适用性)怎么做成硬过滤而不是相似度匹配。
|
|
105
|
+
- **第 5 段 C 层引导**:首次接入问客户什么、readiness 怎么判、缺什么怎么提示。
|
|
106
|
+
- **第 6 段 对其余 14 个 skill 的要求**:证据契约的落地面(哪些工具要补
|
|
107
|
+
Evidence 元数据:来源、查询、时间基准)。
|
|
108
|
+
- **第 7 段 测试与 Eval**:PPT 第 16 页四类指标——首次有效证据耗时、关键证据
|
|
109
|
+
召回率、**错误 Confirmed 率**、下一步可执行率——怎么变成 CI 里跑得动的东西。
|
|
110
|
+
|
|
111
|
+
## 已知的物理层缺口(与 MHS 无关,但同一块拼图)
|
|
112
|
+
|
|
113
|
+
PPT 第 9/10/13 页反复指向 ESXi 以下:BMC、Core Dump、SMART/NVMe、驱动固件、
|
|
114
|
+
物理交换机。第 13 页那个 vSAN 案例卡在 Probable,原因写得很直白:
|
|
115
|
+
**"缺口:SMART/NVMe 直接诊断"**。家族今天对这一层完全是盲的。
|
|
116
|
+
|
|
117
|
+
补一个 Redfish/BMC + SMART/NVMe 证据源,是让「Probable → Confirmed」走通的
|
|
118
|
+
前提。用普通 MCP 就够,不必等 Anthropic 的 Model Hardware Standard(2026-08-27
|
|
119
|
+
research preview,目标是实验室仪器与先进制造,不是数据中心基础设施)。
|
|
120
|
+
接口按 read 原语设计,将来若 MHS 开源可平移。
|
|
@@ -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.9"
|
|
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"
|
|
@@ -37,6 +37,13 @@ markers = [
|
|
|
37
37
|
"capability: Capability evals — scored trends, not pass/fail gates. Excluded from the default run (they measure quality, so <100% is expected and must not read as a broken build). Run them with: pytest -m capability",
|
|
38
38
|
]
|
|
39
39
|
addopts = "-m 'not capability'"
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Homepage = "https://github.com/vmware-skills/VMware-Debug"
|
|
43
|
+
Repository = "https://github.com/vmware-skills/VMware-Debug"
|
|
44
|
+
Issues = "https://github.com/vmware-skills/VMware-Debug/issues"
|
|
45
|
+
Changelog = "https://github.com/vmware-skills/VMware-Debug/blob/main/RELEASE_NOTES.md"
|
|
46
|
+
|
|
40
47
|
[dependency-groups]
|
|
41
48
|
dev = [
|
|
42
49
|
"pytest>=8.0,<10.0",
|
|
@@ -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.9",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "vmware-debug",
|
|
15
|
-
"version": "1.8.
|
|
15
|
+
"version": "1.8.9",
|
|
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":["VMWARE_AUDIT_APPROVED_BY","VMWARE_AUDIT_RATIONALE"],"bins":["vmware-policy"]},"primaryEnv":"NONE","homepage":"https://github.com/
|
|
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
|
{vmware_debug-1.8.7 → vmware_debug-1.8.9}/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
|
|
|
@@ -131,4 +131,4 @@ Local-model compatibility is an explicit design constraint for this family, and
|
|
|
131
131
|
the evidence base is small. If you evaluate a model against this skill —
|
|
132
132
|
Qwen, Mistral, Granite, or anything else — a report of what worked and what did
|
|
133
133
|
not is genuinely useful:
|
|
134
|
-
[github.com/
|
|
134
|
+
[github.com/vmware-skills/VMware-Debug/issues](https://github.com/vmware-skills/VMware-Debug/issues).
|
|
@@ -31,7 +31,7 @@ routes fixes to (vmware-aiops, vmware-pilot).
|
|
|
31
31
|
> **Disclaimer**: Community-maintained open-source project, **not affiliated with,
|
|
32
32
|
> endorsed by, or sponsored by VMware, Inc. or Broadcom Inc.**
|
|
33
33
|
|
|
34
|
-
1. **Source Code** — https://github.com/
|
|
34
|
+
1. **Source Code** — https://github.com/vmware-skills/VMware-Debug (MIT).
|
|
35
35
|
2. **Credentials** — none. debug holds no secrets and connects to nothing.
|
|
36
36
|
3. **Network** — none. All tools are local pure functions over event data the
|
|
37
37
|
agent supplies.
|
|
@@ -296,59 +296,59 @@ toml = [
|
|
|
296
296
|
|
|
297
297
|
[[package]]
|
|
298
298
|
name = "cryptography"
|
|
299
|
-
version = "
|
|
299
|
+
version = "50.0.0"
|
|
300
300
|
source = { registry = "https://pypi.org/simple" }
|
|
301
301
|
dependencies = [
|
|
302
302
|
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
|
303
303
|
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
|
304
304
|
]
|
|
305
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
305
|
+
sdist = { url = "https://files.pythonhosted.org/packages/de/41/6cbdcf9142d00fe82836fbb51e503e58088575cf7a0fe1dbff6695bf0840/cryptography-50.0.0.tar.gz", hash = "sha256:eeac2acb5a20ed25e0ad6d1df9891a520b78b404266b6d11778f25d5d691a6c9", size = 880201, upload-time = "2026-07-31T14:25:10.11Z" }
|
|
306
306
|
wheels = [
|
|
307
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
308
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
309
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
310
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
311
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
312
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
313
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
314
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
315
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
316
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
317
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
318
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
319
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
320
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
321
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
322
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
323
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
324
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
325
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
326
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
327
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
328
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
329
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
330
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
331
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
332
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
333
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
334
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
335
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
336
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
337
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
338
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
339
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
340
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
341
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
342
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
343
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
344
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
345
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
346
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
347
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
348
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
349
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
350
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
351
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
307
|
+
{ url = "https://files.pythonhosted.org/packages/c5/5c/59086b4aac5e879d38ddbcf74e4be7ade89cebc3eb199a55da998c3bb46a/cryptography-50.0.0-cp311-abi3-macosx_11_0_arm64.whl", hash = "sha256:031e2d5dd4bb9caa3ca9c82e5a197fd8ae680232cee62603d1a813f3f07e3d03", size = 4001252, upload-time = "2026-07-31T14:23:33.331Z" },
|
|
308
|
+
{ url = "https://files.pythonhosted.org/packages/57/ef/8f2df13c7216bcad3e1c74e07f6e193d93e998e114f524a53877c9af27ad/cryptography-50.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:fd9192b7b70c573d7f214eb1ae35e00d359f6f5e4b27c7e21e30de1fc6204645", size = 4719554, upload-time = "2026-07-31T14:23:35.611Z" },
|
|
309
|
+
{ url = "https://files.pythonhosted.org/packages/d9/41/029086c34d91052fc3b88bcc8056f709a7c915c7a23b235a54eb800b1c97/cryptography-50.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:06a32a980526a6ab9a4b9bf8f7385800791e2bb960903cb6b530e4817509a3b7", size = 4702130, upload-time = "2026-07-31T14:23:37.635Z" },
|
|
310
|
+
{ url = "https://files.pythonhosted.org/packages/7d/ff/b6ce0954962e7f7b969f850a883744197bb3910bdfd7b6da162eab7d9f68/cryptography-50.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:a1b30560f2acc95aa8b2e06e716a13dbfc97314747b80d9707e307f77b40d6b3", size = 4725244, upload-time = "2026-07-31T14:23:39.471Z" },
|
|
311
|
+
{ url = "https://files.pythonhosted.org/packages/06/1e/63a1027cb7fec360a182208e1b7767d5aa1fe57be3d6aa856e69a321edc0/cryptography-50.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:8d89f3976b10b4ce31118de72329025f70d2c6ead14a8217c5514dd2c6d5a78f", size = 5342265, upload-time = "2026-07-31T14:23:41.286Z" },
|
|
312
|
+
{ url = "https://files.pythonhosted.org/packages/6b/72/a1116d683a6d7ece94590013882515de087edf9ef0e6292aae615a44df73/cryptography-50.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b42a28c1844fd9de8f3f7d540e36b66f3a9c83fceac7170ebc7a6a19edd9dcae", size = 4734609, upload-time = "2026-07-31T14:23:43.139Z" },
|
|
313
|
+
{ url = "https://files.pythonhosted.org/packages/15/37/36a9c479bbe49acea2636c7fd3360d20f7b7e079c300352011c44850b181/cryptography-50.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:900131fafd8aead39ac7dd3a7e833be754c17a95cfd91221636949fe4eb0aa8a", size = 4356517, upload-time = "2026-07-31T14:23:44.939Z" },
|
|
314
|
+
{ url = "https://files.pythonhosted.org/packages/32/98/8a151d64367204cbc63ec65d37502f1d9c53cf4bfc6ec3c532614dbec60d/cryptography-50.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:07949c449a1abcf60d1ee6e88956d89404c7df3c8258f46589e912988e551987", size = 4724529, upload-time = "2026-07-31T14:23:46.93Z" },
|
|
315
|
+
{ url = "https://files.pythonhosted.org/packages/22/f6/ec13b470172126464a86bf54d2294a46d29837fc51ba3e45d4047946fb5e/cryptography-50.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:f89831ef99dd7dd169ab06d63a831adb9e20a87aac6d380266bbda5823349169", size = 5299852, upload-time = "2026-07-31T14:23:48.851Z" },
|
|
316
|
+
{ url = "https://files.pythonhosted.org/packages/da/3a/f05e32c99d440c9bb891ea0e36c9091891e36be5a9a87ab2ee6ea20729f6/cryptography-50.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:82148ec5bddac30b51a5b3c1945075f896fa022cb93f8e4a01e9f6ee95292c5f", size = 4734462, upload-time = "2026-07-31T14:23:50.861Z" },
|
|
317
|
+
{ url = "https://files.pythonhosted.org/packages/ca/dc/bd72b26be8953f80625f63151efd38eee71c76ca6cf591c08ff34615a79e/cryptography-50.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1489e263a8048bb8b6a8bac662eb2d402ea5d2b7b4699b72f385f1e2772db105", size = 4852708, upload-time = "2026-07-31T14:23:52.715Z" },
|
|
318
|
+
{ url = "https://files.pythonhosted.org/packages/27/20/c930314a2ab476d15dec966ec87e2e9637bb02b06106b12c0396c57bb603/cryptography-50.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:7cec5b856506da6defb290f30c9ee687d5f5e8cb0bd3f6459dde43b0b4fa40ef", size = 5004179, upload-time = "2026-07-31T14:23:54.887Z" },
|
|
319
|
+
{ url = "https://files.pythonhosted.org/packages/32/2e/c9db68a0c4bfa28e310707527c0ee3a2bd254104d2e02e68f368e197aa4c/cryptography-50.0.0-cp311-abi3-win_amd64.whl", hash = "sha256:bd1c592e4d5974f0d08d4888e432157adba757c66da0246918e43677fafa2d30", size = 3840395, upload-time = "2026-07-31T14:23:56.677Z" },
|
|
320
|
+
{ url = "https://files.pythonhosted.org/packages/c3/fb/951032a3bf22a5697c83183fb6294a4843772947a70e616c57b3ff5f522e/cryptography-50.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:49e7d93abdbd2990caced757e5fade25302f719c3c8fb6e6fff2dde98999fc41", size = 3989258, upload-time = "2026-07-31T14:23:58.881Z" },
|
|
321
|
+
{ url = "https://files.pythonhosted.org/packages/d4/67/91eb047e69c5e845f2f14b8a2e4a1aab0f283cb885531e9e22c8adb176bc/cryptography-50.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:19736989797678c6af1e55cd49055cdbcb55d8f6b5583ac5335f933aba9101dc", size = 4700648, upload-time = "2026-07-31T14:24:00.702Z" },
|
|
322
|
+
{ url = "https://files.pythonhosted.org/packages/30/82/85f0f7425c856b9f96459411eb12e74ef72df9caf6f8f15bf23a33ff131f/cryptography-50.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80b63928fa35083b33966ce1efb70e5b9607181e49dcd1c22c8c005e319f667f", size = 4682442, upload-time = "2026-07-31T14:24:02.538Z" },
|
|
323
|
+
{ url = "https://files.pythonhosted.org/packages/1a/28/b555a365adff1cca2fbe7b9e487d68a40de6bc67ff2cb587473eb43de0e7/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:d58c3db7cd6eed54e6c06744db55456b65ebd7492ddeae9c1e93cfca7aa857d3", size = 4707596, upload-time = "2026-07-31T14:24:04.394Z" },
|
|
324
|
+
{ url = "https://files.pythonhosted.org/packages/72/d8/f52538140cc719df62a01cf87d1c7142318d235817109d6f4054d7c352d6/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:df2a58a472f332225671c35b0a830208b86d004f82baa8530fa3782c85646533", size = 5314552, upload-time = "2026-07-31T14:24:06.31Z" },
|
|
325
|
+
{ url = "https://files.pythonhosted.org/packages/38/14/6120e5bd7c5aa022ad15424ba4d5c5269d0d9448ed4d55e492ea91e3c1c4/cryptography-50.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:11b74db56cdbe3cdee6e3f6982ecb70334fa10dce99ed58bf7894aaaa3b2a037", size = 4717113, upload-time = "2026-07-31T14:24:08.349Z" },
|
|
326
|
+
{ url = "https://files.pythonhosted.org/packages/fa/71/190bf38c3ee2e0f8efc9860ae100c9df4169742eef274b91e7aa1cb133b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f59e38625469987d7ef6d495323c55e7db6c212eaf6112267e0d3b565a2e9c9f", size = 4338580, upload-time = "2026-07-31T14:24:10.227Z" },
|
|
327
|
+
{ url = "https://files.pythonhosted.org/packages/3a/63/504ccfbbe61fd8aa983f7f146399cdf034c72c2fc55f5b2dfdcdcdb20c99/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:ecfed7367f965a0328cfbdd70da860f15441f002f613185668c6e6ebf5a0ac11", size = 4707038, upload-time = "2026-07-31T14:24:12.169Z" },
|
|
328
|
+
{ url = "https://files.pythonhosted.org/packages/01/77/2cf79bbfc4d12ca106437a6e170d6aaa01a373e93093118aaaef0e801bd4/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:9aa87839c383bdbab6ef865787a1fb877af8dd03464c4400322726feaaadfc6d", size = 5273110, upload-time = "2026-07-31T14:24:14.38Z" },
|
|
329
|
+
{ url = "https://files.pythonhosted.org/packages/e5/45/8aae2972c520145377ea3559a605a899bebe227bf070b33cdb445929a9b9/cryptography-50.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:6ba6a53445bd3cfa809ef3ef5f1589aa6ba08784a1d962bf47d0940e871dab1c", size = 4716439, upload-time = "2026-07-31T14:24:16.415Z" },
|
|
330
|
+
{ url = "https://files.pythonhosted.org/packages/7b/20/4fe50b619a48c2525cc46e2dbc1ac490708d704be5d467bdaac6dc955682/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:3f5735ffe4996d28b809371756219f5354864902a3b9e7c0b9ee87041209fc9c", size = 4837383, upload-time = "2026-07-31T14:24:18.553Z" },
|
|
331
|
+
{ url = "https://files.pythonhosted.org/packages/92/91/3a31366e183343d3703f8995c095f5734676bd6938118047e50fcf279eb4/cryptography-50.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:1b4a266766514614f8aa60416e71f2fc6e575d36e7bdc90f644fadb2f4b75b95", size = 4985772, upload-time = "2026-07-31T14:24:20.385Z" },
|
|
332
|
+
{ url = "https://files.pythonhosted.org/packages/74/9a/02ffe35b2853d121689871eb5dce862092562b3a1ed5cc98f1aaed441506/cryptography-50.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:12b9c6996425c76ea6c457ace4f3073e715b8c545add07cd1a8f3a4f90691269", size = 3816291, upload-time = "2026-07-31T14:24:22.125Z" },
|
|
333
|
+
{ url = "https://files.pythonhosted.org/packages/03/37/73d005be173aff344af30e9fd2a576575cb2391a7101d9cd3842e1fa8cce/cryptography-50.0.0-cp39-abi3-macosx_11_0_arm64.whl", hash = "sha256:ccdc4a71a4dabae05de219404f9f4abc38e3b58422177ff93d0da05967dafa07", size = 4036009, upload-time = "2026-07-31T14:24:24.122Z" },
|
|
334
|
+
{ url = "https://files.pythonhosted.org/packages/ff/c6/7a6202a534e32103a285b7834a120869557fe198d51d7cfe59754c8bda9c/cryptography-50.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:910e1d2668e7de9648f2bcee30e180db2a6b15c30f887d7c4c93ddf96e3992e3", size = 4745252, upload-time = "2026-07-31T14:24:26.118Z" },
|
|
335
|
+
{ url = "https://files.pythonhosted.org/packages/85/4f/0fa8c2f4428198f15d9ff8d63400e27afbf94ce833f6108da1eb3753f945/cryptography-50.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:a91296cb61e8df6f86d0c19cc4068228da256bf59bf86049fbd821084565327f", size = 4728939, upload-time = "2026-07-31T14:24:27.994Z" },
|
|
336
|
+
{ url = "https://files.pythonhosted.org/packages/d1/63/54dd723490ba2dc09b299682c10b38db38f159728bcaae8c591b8af2f22d/cryptography-50.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:e722f16708d854fe924790e051061f6704a472c3bac347b6fd88033ea8dd0dc5", size = 4748483, upload-time = "2026-07-31T14:24:30.254Z" },
|
|
337
|
+
{ url = "https://files.pythonhosted.org/packages/1d/dd/7c77d26285cc7f6991efce64a0f5b4f9383bfa5dd8c5033003eaf7db4cdb/cryptography-50.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:d764dcf130c428ef66786f866dd750f53182bc608813489915e9fc106bb0c82f", size = 5367599, upload-time = "2026-07-31T14:24:32.457Z" },
|
|
338
|
+
{ url = "https://files.pythonhosted.org/packages/46/c9/f60aed34c013f317f92817b6c171c2d22a78270fa41109bd4b08af26b194/cryptography-50.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:105110f43a471dbd0060b9c9516cb8a6a79233631a04cc2ba16f28323ac6e025", size = 4762647, upload-time = "2026-07-31T14:24:34.599Z" },
|
|
339
|
+
{ url = "https://files.pythonhosted.org/packages/be/f3/f9a0173b139372c3a48ed98154b45cc6b9de17c789d5ab552e621c293609/cryptography-50.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:828743d939e9629bc267b8e2d08d8bb67cd4319c771a33d4b18b22dd8fb7440a", size = 4385197, upload-time = "2026-07-31T14:24:36.647Z" },
|
|
340
|
+
{ url = "https://files.pythonhosted.org/packages/d8/36/83bb81f6e569bc38e1e4a7bc80f29b46bb9601920bc455fc8e888f5d5742/cryptography-50.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:2a8183b489dc1f7f80f135780fadc1108f14b31b8a40411c7a5b17425f65f28b", size = 4748095, upload-time = "2026-07-31T14:24:39.493Z" },
|
|
341
|
+
{ url = "https://files.pythonhosted.org/packages/6b/16/d3008eff98c764979865834c3d386d4fd041b5f52e7f34fc29ac1a5eb515/cryptography-50.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6e7d61120573a7f2cd94cc095f9e81f6967c61ccdf194285aa143ecec8e0b708", size = 5325948, upload-time = "2026-07-31T14:24:41.556Z" },
|
|
342
|
+
{ url = "https://files.pythonhosted.org/packages/9c/f8/d97f9603efda3888187bfdb893f26c41be4735c10631d05d284ee6b047c4/cryptography-50.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:37fdb0d0111f1e2ff07139dfb79f1b49531f8e213c46f1163dd7642979b58c47", size = 4762400, upload-time = "2026-07-31T14:24:43.636Z" },
|
|
343
|
+
{ url = "https://files.pythonhosted.org/packages/64/a2/4615c8f7d81a00b1d6e6afe19f694e1543582349fb5f4076f6cb5dc36485/cryptography-50.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87f62a3d3b9888ed0fdde100ec06aa61ca9cd44bad9057d1dff9a516b5f5bb9", size = 4878208, upload-time = "2026-07-31T14:24:45.522Z" },
|
|
344
|
+
{ url = "https://files.pythonhosted.org/packages/d2/1a/efcfb02f91407149a0dacffffab791f7e19bf6385f63b3666dc8b5e5c9c8/cryptography-50.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:65c2c3add92b45fd0709db8594536aea39c2a67af0e27ffcf049c498501140b7", size = 5037050, upload-time = "2026-07-31T14:24:47.697Z" },
|
|
345
|
+
{ url = "https://files.pythonhosted.org/packages/57/30/4a22984d4f1bdfb8c054f07a92bc176b97a3134cc1d6c4b3bffb1f3688b4/cryptography-50.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:d24fead1d4d076e1bfb006dcec392074a3cd8d7b4fc8a595aa64073b2b7a96ba", size = 3874135, upload-time = "2026-07-31T14:24:50.085Z" },
|
|
346
|
+
{ url = "https://files.pythonhosted.org/packages/9d/3e/e54cde8c01631a5a8226ccd617eab9e57fd5cfdad90f1a9e6bb570794631/cryptography-50.0.0-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:5e34edd123674534acd70147f0ca331eaa2c74e6325fb2028c886aa26ba0b68c", size = 3963170, upload-time = "2026-07-31T14:24:51.968Z" },
|
|
347
|
+
{ url = "https://files.pythonhosted.org/packages/01/b6/0b9e125e90f3d2dcf599a218a899cda7326a3158cfa258723f0b398b08f6/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:8eb5e1172eb569ea8a872796576e6a67c276351728b6455d5beb01242b027c6a", size = 4692441, upload-time = "2026-07-31T14:24:53.743Z" },
|
|
348
|
+
{ url = "https://files.pythonhosted.org/packages/53/c9/a5151588710785a96d7bc4de27d4cd62f263bbbcb203cfe29df537eb6505/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:910d11e1a385c654bf738bf3e6b8e6ed5de0f5610fcae2be9e5b398d8081d20e", size = 4699810, upload-time = "2026-07-31T14:24:55.746Z" },
|
|
349
|
+
{ url = "https://files.pythonhosted.org/packages/c7/1a/15b92b25eb6ce3089cd49377ae990a0f3ad485a510f968aed1f19dbdcdf2/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:62598a8a57f815db4c6259a4e97d857dab56697e7de8e8ab02352ab74da1995d", size = 4691924, upload-time = "2026-07-31T14:24:58.082Z" },
|
|
350
|
+
{ url = "https://files.pythonhosted.org/packages/62/15/219075012ab13e8905f3cd572204f4acb4b111df787104346b9bc0cea789/cryptography-50.0.0-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:07479a1cb08219ab719147e742e76090c9c773321959bb94946fffdd397a6437", size = 4699593, upload-time = "2026-07-31T14:24:59.951Z" },
|
|
351
|
+
{ url = "https://files.pythonhosted.org/packages/8e/b5/c2c5fce26f0ee40d21bafe7f191d29a34b35a65ac4fe8a1191d1983612e9/cryptography-50.0.0-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:c99c003e088647b8a5b7c145d6f78c335f6348332b62e142d411c4b63d1460b9", size = 3813796, upload-time = "2026-07-31T14:25:02.298Z" },
|
|
352
352
|
]
|
|
353
353
|
|
|
354
354
|
[[package]]
|
|
@@ -1293,7 +1293,7 @@ wheels = [
|
|
|
1293
1293
|
|
|
1294
1294
|
[[package]]
|
|
1295
1295
|
name = "vmware-debug"
|
|
1296
|
-
version = "1.8.
|
|
1296
|
+
version = "1.8.8"
|
|
1297
1297
|
source = { editable = "." }
|
|
1298
1298
|
dependencies = [
|
|
1299
1299
|
{ name = "mcp", extra = ["cli"] },
|
|
@@ -1326,14 +1326,14 @@ dev = [
|
|
|
1326
1326
|
|
|
1327
1327
|
[[package]]
|
|
1328
1328
|
name = "vmware-policy"
|
|
1329
|
-
version = "1.8.
|
|
1329
|
+
version = "1.8.9"
|
|
1330
1330
|
source = { registry = "https://pypi.org/simple" }
|
|
1331
1331
|
dependencies = [
|
|
1332
1332
|
{ name = "pyyaml" },
|
|
1333
1333
|
{ name = "rich" },
|
|
1334
1334
|
{ name = "typer" },
|
|
1335
1335
|
]
|
|
1336
|
-
sdist = { url = "https://files.pythonhosted.org/packages/
|
|
1336
|
+
sdist = { url = "https://files.pythonhosted.org/packages/4a/45/ce66d8f080fa8c903bd031b79930a5816eb22d43c32860ae97356acd4f8d/vmware_policy-1.8.9.tar.gz", hash = "sha256:ad28807dd16f2ef89c0e75fbe1c09d70324ec49ce451d448e2c6e3f63802356a", size = 125604, upload-time = "2026-08-01T03:03:09.696Z" }
|
|
1337
1337
|
wheels = [
|
|
1338
|
-
{ url = "https://files.pythonhosted.org/packages/
|
|
1338
|
+
{ url = "https://files.pythonhosted.org/packages/87/8d/4c79f9a488998cd5143cbccd4a1f6018cae610edbc3cb145c909c28becd6/vmware_policy-1.8.9-py3-none-any.whl", hash = "sha256:5f3bada3b252d44436c3d0af22fafdf466241021b7f70586dbe29b8806df5d24", size = 47502, upload-time = "2026-08-01T03:03:05.246Z" },
|
|
1339
1339
|
]
|
|
@@ -16,6 +16,7 @@ from mcp.server.fastmcp import FastMCP
|
|
|
16
16
|
from vmware_policy import sanitize, set_environment_resolver
|
|
17
17
|
|
|
18
18
|
from vmware_debug.mcp import tools as t
|
|
19
|
+
from vmware_debug import __version__
|
|
19
20
|
|
|
20
21
|
logger = logging.getLogger("mcp_server")
|
|
21
22
|
|
|
@@ -118,6 +119,11 @@ def build_server() -> FastMCP:
|
|
|
118
119
|
"""Construct and configure the MCP server."""
|
|
119
120
|
server = FastMCP("vmware-debug")
|
|
120
121
|
|
|
122
|
+
# FastMCP takes no version argument and leaves the lowlevel server's at
|
|
123
|
+
# None, which makes `initialize` answer with the MCP SDK's version rather
|
|
124
|
+
# than ours. Set it so a client can tell which release it is talking to.
|
|
125
|
+
server._mcp_server.version = __version__
|
|
126
|
+
|
|
121
127
|
@server.tool(name="incident_timeline", annotations=_READ)
|
|
122
128
|
def _incident_timeline_impl(
|
|
123
129
|
events: list[dict],
|
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
"""vmware-debug declares a constant environment, and must keep doing so.
|
|
2
|
-
|
|
3
|
-
Policy rules scope by environment. The baseline treats a target that declares
|
|
4
|
-
none as unknown: today a state-changing operation against it runs but logs a
|
|
5
|
-
warning (``require_declared_environment: warn``), and the next major release
|
|
6
|
-
refuses it outright (``true``).
|
|
7
|
-
|
|
8
|
-
Every skill with a config answers this per target. vmware-debug has none and no
|
|
9
|
-
connection to declare one about — its tools are pure correlation over event
|
|
10
|
-
dicts the calling agent has already fetched with other skills' read tools. No
|
|
11
|
-
network, no writes, and no operation above read risk. So it registers a
|
|
12
|
-
constant ``local`` resolver: the claim "nothing here touches a remote VMware
|
|
13
|
-
estate" is simply true.
|
|
14
|
-
|
|
15
|
-
Nothing this skill ships is gated under either setting today, so this file is
|
|
16
|
-
about keeping that honest as the skill changes: if debug ever grows a tool that
|
|
17
|
-
writes to a local store, the declaration is already in place and correct, and a
|
|
18
|
-
refactor that drops the registration fails here rather than at the moment
|
|
19
|
-
enforcement lands.
|
|
20
|
-
"""
|
|
21
|
-
|
|
22
|
-
from __future__ import annotations
|
|
23
|
-
|
|
24
|
-
import importlib
|
|
25
|
-
|
|
26
|
-
import pytest
|
|
27
|
-
|
|
28
|
-
import vmware_policy.environment as env_mod
|
|
29
|
-
from vmware_debug.mcp_server import server
|
|
30
|
-
from vmware_policy.environment import resolve_environment, set_environment_resolver
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
@pytest.fixture()
|
|
34
|
-
def _policy():
|
|
35
|
-
"""The policy engine, or a skip.
|
|
36
|
-
|
|
37
|
-
``vmware_policy.policy._load_rules`` imports PyYAML, but vmware-policy
|
|
38
|
-
declares only typer + rich — so constructing a PolicyEngine raises
|
|
39
|
-
ModuleNotFoundError in this skill's environment. Every other skill happens
|
|
40
|
-
to pull PyYAML in for its own config; vmware-debug has no config and so
|
|
41
|
-
does not. It never calls @vmware_tool either, so this is latent here rather
|
|
42
|
-
than broken.
|
|
43
|
-
|
|
44
|
-
Skipping (not stubbing) keeps that honest: these assertions start running
|
|
45
|
-
for real the day vmware-policy declares the dependency.
|
|
46
|
-
"""
|
|
47
|
-
pytest.importorskip(
|
|
48
|
-
"yaml",
|
|
49
|
-
reason="vmware-policy imports PyYAML without declaring it; "
|
|
50
|
-
"vmware-debug has no YAML config so it is absent here",
|
|
51
|
-
)
|
|
52
|
-
from vmware_policy.policy import reset_policy_engine
|
|
53
|
-
|
|
54
|
-
reset_policy_engine()
|
|
55
|
-
yield
|
|
56
|
-
reset_policy_engine()
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
@pytest.fixture()
|
|
60
|
-
def baseline(_policy):
|
|
61
|
-
"""The shipped policy baseline — currently the warn-only migration setting."""
|
|
62
|
-
from vmware_policy.policy import get_policy_engine
|
|
63
|
-
|
|
64
|
-
get_policy_engine()
|
|
65
|
-
yield
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
@pytest.fixture()
|
|
69
|
-
def enforcing(_policy, tmp_path):
|
|
70
|
-
"""The same rules with the requirement switched on, as the next major
|
|
71
|
-
release will ship it."""
|
|
72
|
-
from vmware_policy.policy import get_policy_engine
|
|
73
|
-
|
|
74
|
-
rules = tmp_path / "rules.yaml"
|
|
75
|
-
rules.write_text("require_declared_environment: true\n")
|
|
76
|
-
get_policy_engine(rules)
|
|
77
|
-
yield
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
@pytest.fixture(autouse=True)
|
|
81
|
-
def _restore_resolver():
|
|
82
|
-
"""Tests here clear/reload the global resolver; put it back afterwards."""
|
|
83
|
-
yield
|
|
84
|
-
importlib.reload(server)
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
class TestConstantResolverIsRegistered:
|
|
88
|
-
def test_importing_the_server_registers_a_resolver(self) -> None:
|
|
89
|
-
set_environment_resolver(None)
|
|
90
|
-
importlib.reload(server)
|
|
91
|
-
|
|
92
|
-
assert env_mod._resolver is not None, (
|
|
93
|
-
"vmware_debug.mcp_server.server must call set_environment_resolver() at import."
|
|
94
|
-
)
|
|
95
|
-
assert env_mod._resolver is server._environment_for
|
|
96
|
-
|
|
97
|
-
def test_registration_is_at_module_level_not_inside_build_server(self) -> None:
|
|
98
|
-
"""Importing alone must be enough — no build_server() call required."""
|
|
99
|
-
set_environment_resolver(None)
|
|
100
|
-
importlib.reload(server) # import only — build_server() not called
|
|
101
|
-
|
|
102
|
-
assert env_mod._resolver is not None
|
|
103
|
-
assert resolve_environment("lab") == server.LOCAL_ENVIRONMENT
|
|
104
|
-
|
|
105
|
-
def test_resolver_reports_a_non_empty_environment(self) -> None:
|
|
106
|
-
importlib.reload(server)
|
|
107
|
-
|
|
108
|
-
# "" is the sentinel for *undeclared*. Anything else is a declaration.
|
|
109
|
-
assert resolve_environment("") != ""
|
|
110
|
-
assert resolve_environment("anything") == server.LOCAL_ENVIRONMENT
|
|
111
|
-
|
|
112
|
-
def test_declaration_is_constant_across_targets(self) -> None:
|
|
113
|
-
importlib.reload(server)
|
|
114
|
-
|
|
115
|
-
for target in ("", "prod-vc01", "vcenter-lab", "nonsense"):
|
|
116
|
-
assert resolve_environment(target) == server.LOCAL_ENVIRONMENT
|
|
117
|
-
|
|
118
|
-
def test_declared_environment_is_not_a_production_label(self) -> None:
|
|
119
|
-
"""`local` must not collide with the environments real rules scope to."""
|
|
120
|
-
assert server.LOCAL_ENVIRONMENT not in ("production", "prod", "staging", "")
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
class TestWriteGateInput:
|
|
124
|
-
"""Debug ships no write tools today. Pin that the value the gate keys on is
|
|
125
|
-
a declaration, so a future local-store write is scoped right on day one
|
|
126
|
-
rather than discovered at the enforcing release."""
|
|
127
|
-
|
|
128
|
-
def test_the_gate_sees_a_declaration_not_a_blank(self) -> None:
|
|
129
|
-
"""``env`` is what PolicyEngine.check_allowed receives; "" is what it
|
|
130
|
-
refuses. This holds regardless of whether PyYAML is installed."""
|
|
131
|
-
importlib.reload(server)
|
|
132
|
-
|
|
133
|
-
assert resolve_environment("") == server.LOCAL_ENVIRONMENT
|
|
134
|
-
|
|
135
|
-
@pytest.mark.parametrize("mode", ["baseline", "enforcing"])
|
|
136
|
-
@pytest.mark.parametrize("risk", ["medium", "high"])
|
|
137
|
-
def test_a_hypothetical_write_is_allowed(self, mode, request, risk) -> None:
|
|
138
|
-
from vmware_policy.policy import get_policy_engine
|
|
139
|
-
|
|
140
|
-
request.getfixturevalue(mode)
|
|
141
|
-
importlib.reload(server)
|
|
142
|
-
|
|
143
|
-
result = get_policy_engine().check_allowed(
|
|
144
|
-
"some_future_local_write", env=resolve_environment(""), risk_level=risk
|
|
145
|
-
)
|
|
146
|
-
assert result.allowed is True
|
|
147
|
-
assert result.rule != "undeclared_environment_warning"
|
|
148
|
-
|
|
149
|
-
def test_without_a_resolver_such_a_write_would_be_refused(self, enforcing) -> None:
|
|
150
|
-
"""Proves the pin above is load-bearing rather than decorative."""
|
|
151
|
-
from vmware_policy.policy import get_policy_engine
|
|
152
|
-
|
|
153
|
-
set_environment_resolver(None)
|
|
154
|
-
|
|
155
|
-
result = get_policy_engine().check_allowed(
|
|
156
|
-
"some_future_local_write", env=resolve_environment(""), risk_level="medium"
|
|
157
|
-
)
|
|
158
|
-
assert result.allowed is False
|
|
159
|
-
assert result.rule == "undeclared_environment"
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
class TestReadsAreNeverGated:
|
|
163
|
-
def test_product_read_tools_work_with_no_resolver_at_all(self) -> None:
|
|
164
|
-
"""Every tool this skill ships is read-only, so the whole surface must
|
|
165
|
-
keep working regardless of any of this."""
|
|
166
|
-
set_environment_resolver(None)
|
|
167
|
-
|
|
168
|
-
from vmware_debug.mcp import tools as t
|
|
169
|
-
|
|
170
|
-
assert t.list_symptom_categories()
|
|
171
|
-
|
|
172
|
-
@pytest.mark.parametrize("mode", ["baseline", "enforcing"])
|
|
173
|
-
def test_reads_allowed_by_policy_under_both_settings(self, mode, request) -> None:
|
|
174
|
-
from vmware_policy.policy import get_policy_engine
|
|
175
|
-
|
|
176
|
-
request.getfixturevalue(mode)
|
|
177
|
-
set_environment_resolver(None)
|
|
178
|
-
|
|
179
|
-
assert get_policy_engine().check_allowed(
|
|
180
|
-
"incident_timeline", env="", risk_level="low"
|
|
181
|
-
).allowed
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/test_tool_description_quality.py
RENAMED
|
File without changes
|
{vmware_debug-1.8.7 → vmware_debug-1.8.9}/tests/eval/capability/test_tool_manifest_budget.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|