vmware-debug 1.11.2__tar.gz → 1.11.4__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.2 → vmware_debug-1.11.4}/.claude-plugin/plugin.json +2 -2
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/.mcp.json +1 -1
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/PKG-INFO +28 -10
- vmware_debug-1.11.4/README-CN.md +72 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/README.md +25 -7
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/RELEASE_NOTES.md +61 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/SECURITY.md +18 -5
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/pyproject.toml +3 -3
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/server.json +3 -3
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/SKILL.md +25 -12
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/references/agent-guardrails.md +4 -4
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/references/capabilities.md +4 -1
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/references/cli-reference.md +3 -1
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/references/setup-guide.md +18 -7
- vmware_debug-1.11.4/tests/__init__.py +9 -0
- vmware_debug-1.11.4/tests/conftest.py +42 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/_scoring.py +2 -2
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/_skill.py +2 -2
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/test_entity_reachability.py +2 -2
- vmware_debug-1.11.4/tests/eval/regression/test_audit_isolation.py +67 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_capability_grader.py +3 -3
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_environment_resolver_isolation.py +1 -1
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_investigation_metrics.py +1 -1
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_tool_annotations.py +3 -2
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_conclusion.py +5 -5
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_evidence.py +2 -2
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_grading.py +5 -5
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_hypotheses.py +1 -1
- vmware_debug-1.11.4/tests/test_case_ledger_concurrency.py +417 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_readiness.py +1 -1
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_store.py +5 -5
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_timeline_close.py +2 -2
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_knowledge.py +1 -1
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/uv.lock +5 -5
- vmware_debug-1.11.4/vmware_debug/__init__.py +9 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/cli.py +29 -4
- vmware_debug-1.11.4/vmware_debug/mcp/__init__.py +3 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/mcp/tools.py +5 -3
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/mcp_server/server.py +28 -20
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/api.py +6 -3
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/conclusion.py +37 -27
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/evidence.py +49 -30
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/hypotheses.py +23 -14
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/knowledge.py +1 -1
- vmware_debug-1.11.4/vmware_debug/ops/cases/store.py +396 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/timeline.py +74 -57
- vmware_debug-1.11.2/README-CN.md +0 -47
- vmware_debug-1.11.2/vmware_debug/__init__.py +0 -8
- vmware_debug-1.11.2/vmware_debug/mcp/__init__.py +0 -2
- vmware_debug-1.11.2/vmware_debug/ops/cases/store.py +0 -184
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/.gitignore +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/docs/plans/2026-08-28-investigation-layer-design.md +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/references/event-envelope.md +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/references/routing.md +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/__init__.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/__init__.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/_family.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/_scores.json +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/conftest.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/test_error_actionability.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/test_tool_description_quality.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/capability/test_tool_manifest_budget.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/__init__.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/_vsphere_event_vocabulary.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_case_id_non_ascii.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_case_plan_max_steps.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_classification_against_vsphere_vocabulary.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_debug_regressions.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_every_tool_parameter_is_documented.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_evidence_payload_contract.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_host_lifecycle_classification.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_result_envelope.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_skill_name_aliases.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/eval/regression/test_spike_resolution.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_ids.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_plan.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_case_tools.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_safe_error_passthrough.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/tests/test_timeline.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/envelope.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/mcp_server/__init__.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/__init__.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/__init__.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/grading.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/ids.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/model.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/payloads.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/plan.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/readiness.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/cases/sources.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/skill_names.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/ops/timeline.py +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/rules/evidence_sources.yaml +0 -0
- {vmware_debug-1.11.2 → vmware_debug-1.11.4}/vmware_debug/rules/grading_rules.yaml +0 -0
|
@@ -2,8 +2,8 @@
|
|
|
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.
|
|
6
|
-
"description": "
|
|
5
|
+
"version": "1.11.4",
|
|
6
|
+
"description": "VMware incident timeline, root-cause routing, local case ledger; no vSphere access. 14 MCP tools.",
|
|
7
7
|
"author": {
|
|
8
8
|
"name": "Wei Zhou",
|
|
9
9
|
"email": "zhouwei008@gmail.com",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: vmware-debug
|
|
3
|
-
Version: 1.11.
|
|
4
|
-
Summary: VMware diagnostic brain —
|
|
3
|
+
Version: 1.11.4
|
|
4
|
+
Summary: VMware diagnostic brain — offline 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
|
|
7
7
|
Project-URL: Issues, https://github.com/vmware-skills/VMware-Debug/issues
|
|
@@ -18,17 +18,13 @@ 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.13.1
|
|
22
22
|
Description-Content-Type: text/markdown
|
|
23
23
|
|
|
24
24
|
<!-- mcp-name: io.github.vmware-skills/vmware-debug -->
|
|
25
25
|
|
|
26
26
|
# VMware Debug
|
|
27
27
|
|
|
28
|
-
> ⚠️ **Work in progress** — the core (event correlation engine, MCP tools, CLI)
|
|
29
|
-
> is built and tested; README, `server.json`, full reference docs, and packaging
|
|
30
|
-
> polish are still landing. Not yet published to PyPI.
|
|
31
|
-
|
|
32
28
|
> **Disclaimer**: Community-maintained open-source project, **not affiliated with,
|
|
33
29
|
> endorsed by, or sponsored by VMware, Inc. or Broadcom Inc.** "VMware" and
|
|
34
30
|
> "vSphere" are trademarks of Broadcom. Source is publicly auditable under the MIT
|
|
@@ -37,21 +33,43 @@ Description-Content-Type: text/markdown
|
|
|
37
33
|
The diagnostic brain of the VMware skill family. You bring the symptom (an error,
|
|
38
34
|
a log dump, a slow VM); this skill runs a systematic investigation, correlates
|
|
39
35
|
events from the other skills into one timeline, ranks root-cause hypotheses, and
|
|
40
|
-
tells you what to check next. It
|
|
41
|
-
never executes fixes
|
|
36
|
+
tells you what to check next. It **never touches vSphere** — it connects to
|
|
37
|
+
nothing and never executes fixes; its only writes are to a local case ledger
|
|
38
|
+
under `$OPS_HOME`. Remediation is routed to `vmware-aiops` (single op) or
|
|
42
39
|
`vmware-pilot` (multi-step, gated), mirroring the `vmware-harden → vmware-pilot`
|
|
43
40
|
advisor/executor split.
|
|
44
41
|
|
|
45
42
|
See [`skills/vmware-debug/SKILL.md`](skills/vmware-debug/SKILL.md) for the full
|
|
46
43
|
methodology, the event-envelope contract, and symptom routing.
|
|
47
44
|
|
|
48
|
-
## MCP tools
|
|
45
|
+
## MCP tools (14 — 7 read, 7 write)
|
|
46
|
+
|
|
47
|
+
The seven writes go to the local case ledger only; none reaches a VMware system.
|
|
48
|
+
|
|
49
|
+
**Correlation** — stateless, for a single look:
|
|
49
50
|
|
|
50
51
|
| Tool | What |
|
|
51
52
|
|---|---|
|
|
52
53
|
| `incident_timeline` | [READ] Correlate pre-fetched events → timeline + spikes + ranked hypotheses + next-check ideas |
|
|
53
54
|
| `list_symptom_categories` | [READ] List recognised symptom categories + what to check for each |
|
|
54
55
|
|
|
56
|
+
**Investigation ledger** — for an incident you will reason about over time:
|
|
57
|
+
|
|
58
|
+
| Tool | What |
|
|
59
|
+
|---|---|
|
|
60
|
+
| `case_open` | [WRITE] Define the event; returns a case id and the grade this environment can reach |
|
|
61
|
+
| `case_readiness` | [READ] What grade this environment can reach, per symptom category, **before** you start |
|
|
62
|
+
| `case_knowledge` | [READ] Which knowledge formats are accepted, what is mounted, and which entries apply to a case |
|
|
63
|
+
| `case_plan` | [READ] What to fetch next — skill, tool and purpose per step; recomputed from the case's current state |
|
|
64
|
+
| `case_list` | [READ] Cases, newest first |
|
|
65
|
+
| `case_get` | [READ] One case: scope, ledger sizes, grade history |
|
|
66
|
+
| `case_hypotheses` | [WRITE] Register a candidate explanation, or read the ledger of what supports and refutes each |
|
|
67
|
+
| `case_submit_evidence` | [WRITE] Record one retrieved fact, with its source, query and time basis |
|
|
68
|
+
| `case_record_gap` | [WRITE] Record what could **not** be retrieved, and how to close it |
|
|
69
|
+
| `case_timeline` | [WRITE] Correlate everything the case has collected into one timeline |
|
|
70
|
+
| `case_grade` | [WRITE] Recompute the conclusion grade from the ledger and record it |
|
|
71
|
+
| `case_close` | [WRITE] Record the final grade, archive, and name what was left open |
|
|
72
|
+
|
|
55
73
|
## Offline / Air-Gapped Install (from source)
|
|
56
74
|
|
|
57
75
|
This project uses the modern PEP 517 build system (hatchling), so there is **no
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
<!-- mcp-name: io.github.vmware-skills/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
|
+
它**从不触碰 vSphere**——不连接任何东西,也从不执行修复;唯一的写入是 `$OPS_HOME` 下的本地案卷。修复一律路由给 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 工具(14 个:7 读、7 写)
|
|
31
|
+
|
|
32
|
+
7 个写工具只写本地案卷,没有一个触及任何 VMware 系统。
|
|
33
|
+
|
|
34
|
+
**关联**——无状态,看一眼用:
|
|
35
|
+
|
|
36
|
+
- `incident_timeline`:[READ] 把已取到的事件关联成 时间线 + 突刺 + 排序后的根因假设 + 下一步检查建议
|
|
37
|
+
- `list_symptom_categories`:[READ] 症状类别及对应的排查路由(不知道查什么时用它)
|
|
38
|
+
|
|
39
|
+
**调查案卷**——需要持续推理的事件:
|
|
40
|
+
|
|
41
|
+
- `case_open`:[WRITE] 定义事件;返回案卷 id 和本环境能达到的结论等级
|
|
42
|
+
- `case_readiness`:[READ] 开始**之前**,按症状类别说明本环境能达到的等级
|
|
43
|
+
- `case_knowledge`:[READ] 接受哪些知识格式、挂载了什么、哪些条目适用于某个案卷
|
|
44
|
+
- `case_plan`:[READ] 下一步该取什么——每步给出 skill、工具和目的;按案卷当前状态重算
|
|
45
|
+
- `case_list`:[READ] 案卷列表,最新的在前
|
|
46
|
+
- `case_get`:[READ] 单个案卷:范围、账本大小、等级历史
|
|
47
|
+
- `case_hypotheses`:[WRITE] 登记一个候选解释,或读取各假设的支持/反驳账本
|
|
48
|
+
- `case_submit_evidence`:[WRITE] 记录一条取到的事实,连同来源、查询和时间基准
|
|
49
|
+
- `case_record_gap`:[WRITE] 记录**没能**取到的东西,以及如何补上
|
|
50
|
+
- `case_timeline`:[WRITE] 把案卷收集到的一切关联成一条时间线
|
|
51
|
+
- `case_grade`:[WRITE] 从账本重算结论等级并记录
|
|
52
|
+
- `case_close`:[WRITE] 记录最终等级、归档,并写明留下了哪些未决项
|
|
53
|
+
|
|
54
|
+
**事件信封**:`{ts, source, severity, entity, text, fields}`。agent 把各源事件归一成此形状再交给
|
|
55
|
+
debug;debug 因此与其它包零运行时依赖。**请把每条事件的 `event_type` 保留在 `fields` 里**——
|
|
56
|
+
分类器除了正文之外也匹配它,而现代 vSphere 多数事件是 `EventEx`:正文是一句通用套话,
|
|
57
|
+
真正说明「这是什么事件」的只有 `eventTypeId`。
|
|
58
|
+
|
|
59
|
+
## 安全
|
|
60
|
+
|
|
61
|
+
结构上离线、无凭据:不连任何 vCenter/NSX/Aria,对 VMware 没有可破坏面,也没有秘密可泄露。
|
|
62
|
+
唯一的写入是本地案卷:证据、缺口、假设和等级历史只增不改;`timeline.md` 由证据重新生成,
|
|
63
|
+
`case.json` 保存当前等级和状态。多个写入者同样成立:每次写案卷都要先拿该案卷的锁文件(`.ledger.lock`,
|
|
64
|
+
独占创建),所以两个进程在共享的 `$OPS_HOME` 里写同一个案卷会被串行化,而不是互相丢条目;每个文件都先写到
|
|
65
|
+
临时文件名再移到位,读者不会读到写了一半的文件(在不支持硬链接的文件系统上,新的证据文件改为原地创建:
|
|
66
|
+
仍然绝不覆盖,但可能被读到写了一半)。崩溃进程留下的锁会连同持有者一起报告,从不自动删除;
|
|
67
|
+
确认没有进程在写该案卷后再手动删除。已发布的 1.11.3 及更早版本不拿这个锁,共享案卷目录的每台机器都要升级。
|
|
68
|
+
详见 [SECURITY.md](SECURITY.md)。
|
|
69
|
+
|
|
70
|
+
## 许可证
|
|
71
|
+
|
|
72
|
+
MIT。
|
|
@@ -2,10 +2,6 @@
|
|
|
2
2
|
|
|
3
3
|
# VMware Debug
|
|
4
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
5
|
> **Disclaimer**: Community-maintained open-source project, **not affiliated with,
|
|
10
6
|
> endorsed by, or sponsored by VMware, Inc. or Broadcom Inc.** "VMware" and
|
|
11
7
|
> "vSphere" are trademarks of Broadcom. Source is publicly auditable under the MIT
|
|
@@ -14,21 +10,43 @@
|
|
|
14
10
|
The diagnostic brain of the VMware skill family. You bring the symptom (an error,
|
|
15
11
|
a log dump, a slow VM); this skill runs a systematic investigation, correlates
|
|
16
12
|
events from the other skills into one timeline, ranks root-cause hypotheses, and
|
|
17
|
-
tells you what to check next. It
|
|
18
|
-
never executes fixes
|
|
13
|
+
tells you what to check next. It **never touches vSphere** — it connects to
|
|
14
|
+
nothing and never executes fixes; its only writes are to a local case ledger
|
|
15
|
+
under `$OPS_HOME`. Remediation is routed to `vmware-aiops` (single op) or
|
|
19
16
|
`vmware-pilot` (multi-step, gated), mirroring the `vmware-harden → vmware-pilot`
|
|
20
17
|
advisor/executor split.
|
|
21
18
|
|
|
22
19
|
See [`skills/vmware-debug/SKILL.md`](skills/vmware-debug/SKILL.md) for the full
|
|
23
20
|
methodology, the event-envelope contract, and symptom routing.
|
|
24
21
|
|
|
25
|
-
## MCP tools
|
|
22
|
+
## MCP tools (14 — 7 read, 7 write)
|
|
23
|
+
|
|
24
|
+
The seven writes go to the local case ledger only; none reaches a VMware system.
|
|
25
|
+
|
|
26
|
+
**Correlation** — stateless, for a single look:
|
|
26
27
|
|
|
27
28
|
| Tool | What |
|
|
28
29
|
|---|---|
|
|
29
30
|
| `incident_timeline` | [READ] Correlate pre-fetched events → timeline + spikes + ranked hypotheses + next-check ideas |
|
|
30
31
|
| `list_symptom_categories` | [READ] List recognised symptom categories + what to check for each |
|
|
31
32
|
|
|
33
|
+
**Investigation ledger** — for an incident you will reason about over time:
|
|
34
|
+
|
|
35
|
+
| Tool | What |
|
|
36
|
+
|---|---|
|
|
37
|
+
| `case_open` | [WRITE] Define the event; returns a case id and the grade this environment can reach |
|
|
38
|
+
| `case_readiness` | [READ] What grade this environment can reach, per symptom category, **before** you start |
|
|
39
|
+
| `case_knowledge` | [READ] Which knowledge formats are accepted, what is mounted, and which entries apply to a case |
|
|
40
|
+
| `case_plan` | [READ] What to fetch next — skill, tool and purpose per step; recomputed from the case's current state |
|
|
41
|
+
| `case_list` | [READ] Cases, newest first |
|
|
42
|
+
| `case_get` | [READ] One case: scope, ledger sizes, grade history |
|
|
43
|
+
| `case_hypotheses` | [WRITE] Register a candidate explanation, or read the ledger of what supports and refutes each |
|
|
44
|
+
| `case_submit_evidence` | [WRITE] Record one retrieved fact, with its source, query and time basis |
|
|
45
|
+
| `case_record_gap` | [WRITE] Record what could **not** be retrieved, and how to close it |
|
|
46
|
+
| `case_timeline` | [WRITE] Correlate everything the case has collected into one timeline |
|
|
47
|
+
| `case_grade` | [WRITE] Recompute the conclusion grade from the ledger and record it |
|
|
48
|
+
| `case_close` | [WRITE] Record the final grade, archive, and name what was left open |
|
|
49
|
+
|
|
32
50
|
## Offline / Air-Gapped Install (from source)
|
|
33
51
|
|
|
34
52
|
This project uses the modern PEP 517 build system (hatchling), so there is **no
|
|
@@ -1,3 +1,64 @@
|
|
|
1
|
+
## v1.11.4 — concurrent writers stop losing case entries
|
|
2
|
+
|
|
3
|
+
Two agents on one case — a supported setup, since `OPS_HOME` can point at a shared folder — lost
|
|
4
|
+
entries: six processes writing 150 gaps and hypotheses each kept 157 of 900 gaps and handed out
|
|
5
|
+
duplicate hypothesis ids. Ledger writes are now serialised by a per-case lock (`.ledger.lock`
|
|
6
|
+
in the case folder), and each write lands atomically. Versions up to and including 1.11.3 do not
|
|
7
|
+
take the lock, so **every machine that shares an `OPS_HOME` needs this version** — one older
|
|
8
|
+
writer on the share can still lose entries.
|
|
9
|
+
|
|
10
|
+
The manifests advertised 2 tools (14 are registered), and the docs called the case-ledger writes
|
|
11
|
+
read-only. Both are corrected, and the docs now say that case data is sensitive, owner-only, and
|
|
12
|
+
kept until you delete the case folder.
|
|
13
|
+
|
|
14
|
+
**OpenClaw hid this skill unless `vmware-debug` was on PATH.** `metadata.openclaw.requires` was
|
|
15
|
+
only `bins: ["vmware-debug"]` — there was no `requires.config` or `requires.env`, unlike most of the
|
|
16
|
+
family. OpenClaw hides a skill whose required binary is missing, and a plugin install runs the
|
|
17
|
+
server through uvx, which never puts `vmware-debug` on PATH, so there the skill was "needs setup / not
|
|
18
|
+
visible to the model" (requirement semantics verified on OpenClaw 2026.6.35). `requires` is now
|
|
19
|
+
`anyBins: ["vmware-debug", "uvx"]`; `optional.env` is unchanged, and the placeholder
|
|
20
|
+
`primaryEnv: "NONE"` is gone.
|
|
21
|
+
|
|
22
|
+
**Install commands in the skill pin this release.** ClawHub reviews SKILL.md and references/,
|
|
23
|
+
not the package they install, so an unpinned `uv tool install` vouched for code nobody reviewed.
|
|
24
|
+
Every install command for this package in the skill now names this version.
|
|
25
|
+
|
|
26
|
+
## v1.11.3 — 398 tests never ran
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
**`tests/__init__.py` was missing, and the whole suite -- 398 tests -- failed at
|
|
30
|
+
collection.** `tests/eval/` and `tests/eval/regression/` were already packages,
|
|
31
|
+
so `from tests.eval.regression._vsphere_event_vocabulary import ...` resolved
|
|
32
|
+
only where the namespace-package fallback happened to work. It did not on
|
|
33
|
+
Windows. One file.
|
|
34
|
+
|
|
35
|
+
**The suite now runs on a cp936 machine.** Round 3 of the VCF 9 field testing ran
|
|
36
|
+
on Windows Server 2025 with locale cp936. Across the family four repos' suites --
|
|
37
|
+
1687 tests -- never executed at all, dying at collection reading our own UTF-8
|
|
38
|
+
sources, and 101 more failed the same way. Most of those were the tests that
|
|
39
|
+
verify the destructive-operation guardrails: the guardrails were fine, the tests
|
|
40
|
+
that check them could not open a file. On the UTF-8 CI every one of them was
|
|
41
|
+
green. A security test that cannot run is not a security test.
|
|
42
|
+
|
|
43
|
+
Every text read and write here names its encoding now, `tests/` included -- the
|
|
44
|
+
previous round fixed only the package, which is why this came back. A gate in
|
|
45
|
+
`family_smoke` scans both trees by AST, and the whole family's suites were re-run
|
|
46
|
+
under an ASCII locale to confirm: 15 of 15 green, from 1 of 15.
|
|
47
|
+
|
|
48
|
+
**`--help` no longer dies on a console that cannot encode it.** On any console
|
|
49
|
+
whose encoding cannot carry the characters in our own help text, `--help` exited
|
|
50
|
+
with a `UnicodeEncodeError` traceback -- unavailable exactly on the machines
|
|
51
|
+
where it is most needed. Four repos were affected; the handler is now relaxed in
|
|
52
|
+
all fifteen so a glyph degrades instead of killing the command.
|
|
53
|
+
|
|
54
|
+
**Unknown tool arguments are refused instead of dropped.** The schema declared
|
|
55
|
+
`additionalProperties: false` and the runtime accepted them anyway, so a filter
|
|
56
|
+
argument whose name a model guessed wrong returned the *unfiltered* result with
|
|
57
|
+
nothing to indicate anything had been discarded. Fixed in vmware-policy 1.12.0
|
|
58
|
+
and in force here.
|
|
59
|
+
|
|
60
|
+
Requires vmware-policy 1.12.0.
|
|
61
|
+
|
|
1
62
|
## v1.11.2 — the resolver hijack, the discarded event identifier, and a parameter that did nothing
|
|
2
63
|
|
|
3
64
|
Three findings from the 2026-08-30 real-hardware re-test.
|
|
@@ -15,11 +15,24 @@ or by email to the maintainer. Please do not open public issues for security bug
|
|
|
15
15
|
|
|
16
16
|
## Security Design
|
|
17
17
|
|
|
18
|
-
###
|
|
19
|
-
vmware-debug has **no
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
### Offline by construction; writes only its own ledger
|
|
19
|
+
vmware-debug has **no network access and no credentials**. It does not connect to
|
|
20
|
+
vCenter, NSX, Aria, or any appliance. Its tools work over event data the
|
|
21
|
+
orchestrating agent has already fetched with the other skills' read tools. Seven
|
|
22
|
+
of its fourteen MCP tools write — only to the local investigation ledger under
|
|
23
|
+
`$OPS_HOME` (default `~/.vmware/cases`). Evidence, gaps, hypotheses and grade
|
|
24
|
+
history are only ever added to; `timeline.md` is regenerated from the evidence
|
|
25
|
+
and `case.json` holds the current grade and state. That holds with several writers
|
|
26
|
+
too: every write to a case takes that case's lock file (`.ledger.lock`, created
|
|
27
|
+
exclusively), so two processes working one case in a shared `$OPS_HOME` are
|
|
28
|
+
serialised rather than losing each other's entries, and every file is written to
|
|
29
|
+
a temporary name and moved into place, so a reader never sees half of one (on a
|
|
30
|
+
filesystem without hard links, a new evidence file is created in place instead:
|
|
31
|
+
still never overwritten, but readable half-written). A lock left by a crashed
|
|
32
|
+
process is reported with its holder and never removed automatically; delete it
|
|
33
|
+
once nothing is writing the case. Released versions up to and including 1.11.3
|
|
34
|
+
do not take the lock, so upgrade every machine that shares a cases folder. There
|
|
35
|
+
is no destructive surface against any VMware system and no secret to leak.
|
|
23
36
|
|
|
24
37
|
### No remediation execution
|
|
25
38
|
debug only *diagnoses* and *recommends*. Any fix is routed to vmware-aiops
|
|
@@ -4,8 +4,8 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "vmware-debug"
|
|
7
|
-
version = "1.11.
|
|
8
|
-
description = "VMware diagnostic brain —
|
|
7
|
+
version = "1.11.4"
|
|
8
|
+
description = "VMware diagnostic brain — offline incident triage, log/event correlation, and root-cause routing across the VMware skill family"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
11
11
|
requires-python = ">=3.10"
|
|
@@ -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.13.1,<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.
|
|
@@ -2,17 +2,17 @@
|
|
|
2
2
|
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
|
|
3
3
|
"name": "io.github.vmware-skills/vmware-debug",
|
|
4
4
|
"title": "VMware Debug",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "VMware incident timeline, root-cause routing, local case ledger; no vSphere access. 14 MCP tools.",
|
|
6
6
|
"repository": {
|
|
7
7
|
"url": "https://github.com/vmware-skills/VMware-Debug",
|
|
8
8
|
"source": "github"
|
|
9
9
|
},
|
|
10
|
-
"version": "1.11.
|
|
10
|
+
"version": "1.11.4",
|
|
11
11
|
"packages": [
|
|
12
12
|
{
|
|
13
13
|
"registryType": "pypi",
|
|
14
14
|
"identifier": "vmware-debug",
|
|
15
|
-
"version": "1.11.
|
|
15
|
+
"version": "1.11.4",
|
|
16
16
|
"runtimeHint": "uvx",
|
|
17
17
|
"packageArguments": [
|
|
18
18
|
{
|
|
@@ -10,7 +10,8 @@ description: >
|
|
|
10
10
|
don't know where to start. Always use this skill for "diagnose this VMware
|
|
11
11
|
issue", "why is my VM slow", "troubleshoot this vSphere error", "what does
|
|
12
12
|
this log mean", "help me figure out what broke" when the context is explicitly
|
|
13
|
-
VMware/vSphere/ESXi/NSX. It
|
|
13
|
+
VMware/vSphere/ESXi/NSX. It never touches vSphere: its only writes are to a
|
|
14
|
+
local case ledger. Do NOT
|
|
14
15
|
use it to execute fixes — single fixes go to vmware-aiops, multi-step gated
|
|
15
16
|
remediation goes to vmware-pilot. Do NOT use it for routine inventory or
|
|
16
17
|
health checks with no problem to solve — use vmware-monitor.
|
|
@@ -19,7 +20,7 @@ installer:
|
|
|
19
20
|
package: vmware-debug
|
|
20
21
|
allowed-tools:
|
|
21
22
|
- Bash
|
|
22
|
-
metadata: {"openclaw":{"requires":{"
|
|
23
|
+
metadata: {"openclaw":{"requires":{"anyBins":["vmware-debug","uvx"]},"optional":{"env":["VMWARE_AUDIT_APPROVED_BY","VMWARE_AUDIT_RATIONALE"],"bins":["vmware-policy"]},"homepage":"https://github.com/vmware-skills/VMware-Debug","os":["macos","linux"]}}
|
|
23
24
|
---
|
|
24
25
|
|
|
25
26
|
# VMware Debug
|
|
@@ -30,7 +31,8 @@ metadata: {"openclaw":{"requires":{"bins":["vmware-debug"]},"optional":{"env":["
|
|
|
30
31
|
|
|
31
32
|
The diagnostic brain of the VMware skill family. You bring the symptom; this skill
|
|
32
33
|
runs the investigation and points at the root cause. It **reads and reasons** — it
|
|
33
|
-
never writes
|
|
34
|
+
never writes to vSphere; its only writes go to its own local case ledger.
|
|
35
|
+
Companion skills do the data collection and the fixing.
|
|
34
36
|
|
|
35
37
|
## What This Skill Does
|
|
36
38
|
|
|
@@ -40,14 +42,16 @@ never writes. Companion skills do the data collection and the fixing.
|
|
|
40
42
|
| Root-cause ranking | Score symptom clusters, surface the most likely cause first | Read |
|
|
41
43
|
| Next-check ideas | Suggest exactly what to look at next (which skill/tool) when you're stuck | Read |
|
|
42
44
|
| Remediation routing | Hand the fix to vmware-aiops (single) or vmware-pilot (gated, multi-step) | Read (routes only) |
|
|
45
|
+
| Investigation ledger | Open a case; record evidence, gaps and hypotheses; grade and close it | Write (local ledger only) |
|
|
43
46
|
|
|
44
|
-
**
|
|
45
|
-
has already gathered with the other skills' read tools
|
|
47
|
+
**No network access of its own, and no write to any VMware system.** It correlates
|
|
48
|
+
data the agent has already gathered with the other skills' read tools; its seven
|
|
49
|
+
write tools touch only the local case ledger.
|
|
46
50
|
|
|
47
51
|
## Quick Install
|
|
48
52
|
|
|
49
53
|
```bash
|
|
50
|
-
uv tool install vmware-debug
|
|
54
|
+
uv tool install vmware-debug==1.11.4
|
|
51
55
|
vmware-debug categories # see what it can diagnose
|
|
52
56
|
```
|
|
53
57
|
|
|
@@ -126,7 +130,7 @@ a recommended plan.
|
|
|
126
130
|
| `case_grade` | [WRITE] Recompute the conclusion grade from the ledger and record it |
|
|
127
131
|
| `case_close` | [WRITE] Record the final grade, archive, and name what was left open |
|
|
128
132
|
|
|
129
|
-
The
|
|
133
|
+
The seven writes go to `$OPS_HOME` (default `~/.vmware/cases/`) and nowhere else.
|
|
130
134
|
|
|
131
135
|
**List envelope** (output of `list_symptom_categories`): `{items, returned, limit, total, truncated, hint}` — read the rows from `items`. `truncated` is always `false` here, which is the point: it states that the catalogue is complete instead of leaving you to infer it.
|
|
132
136
|
|
|
@@ -267,11 +271,20 @@ vmware-debug mcp # start stdio MCP server (proxy-
|
|
|
267
271
|
|
|
268
272
|
## Audit & Safety
|
|
269
273
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
274
|
+
No network, nothing executed. The seven [WRITE] tools write only to the local case
|
|
275
|
+
ledger under `$OPS_HOME`; nothing here touches a remote VMware estate. Evidence, gaps,
|
|
276
|
+
hypotheses and grade history are only ever added to — `timeline.md` is regenerated from
|
|
277
|
+
the evidence and `case.json` holds the current grade and state. Remediation is always routed to
|
|
278
|
+
aiops/pilot, where the double-confirm / approval / audit gates live (audit DB
|
|
279
|
+
`~/.vmware/audit.db`). debug has no config and no connection, so it registers no
|
|
280
|
+
environment resolver, and its tools do not pass through the policy engine — no policy
|
|
281
|
+
rule applies to them. See `references/setup-guide.md`.
|
|
282
|
+
|
|
283
|
+
**Case data is sensitive and is kept until you delete it.** Each case lives in
|
|
284
|
+
`$OPS_HOME/cases/<case-id>/` (default `~/.vmware/cases/`), created owner-only (`0700`).
|
|
285
|
+
It holds whatever evidence was submitted — host names, addresses, log and event text.
|
|
286
|
+
Nothing is deleted automatically: `case_close` records the grade and marks the case
|
|
287
|
+
closed but keeps its files. Remove a case by deleting its folder.
|
|
275
288
|
|
|
276
289
|
## License
|
|
277
290
|
|
{vmware_debug-1.11.2 → vmware_debug-1.11.4}/skills/vmware-debug/references/agent-guardrails.md
RENAMED
|
@@ -16,7 +16,7 @@ vmware-debug are specific to this skill.
|
|
|
16
16
|
|
|
17
17
|
vmware-debug exposes 14 MCP tools: 7 reads and 7 writes. It connects to nothing
|
|
18
18
|
and holds no credentials — the calling agent gathers events from the other
|
|
19
|
-
skills, normalises them, and hands them over. The
|
|
19
|
+
skills, normalises them, and hands them over. The seven writes go to the local
|
|
20
20
|
investigation ledger under `~/.vmware/cases/`, never to a VMware system. That
|
|
21
21
|
makes it the safest skill in the family to point a small model at — and the one
|
|
22
22
|
most exposed to the model's reasoning, because its output *is* an
|
|
@@ -41,12 +41,12 @@ These are structural, so it cannot.
|
|
|
41
41
|
|
|
42
42
|
| Guardrail you would otherwise prompt for | Now enforced by |
|
|
43
43
|
|---|---|
|
|
44
|
-
| "Work read-only and never modify anything" | **The tool surface itself.**
|
|
45
|
-
| "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. |
|
|
44
|
+
| "Work read-only and never modify anything" | **The tool surface itself.** No tool reaches a VMware system. The seven [WRITE] tools write only to this skill's own local case ledger, so there is nothing in vSphere to withhold and nothing to switch off. |
|
|
45
|
+
| "Diagnose only — never apply the fix you propose" | **Structural.** This skill has no tool that changes anything outside its own ledger, and it holds no connection to vCenter, NSX or anything else. Remediation is routed to vmware-aiops or vmware-pilot by the calling agent. |
|
|
46
46
|
| "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. |
|
|
47
47
|
| "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. |
|
|
48
48
|
| "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. |
|
|
49
|
-
| "Log everything you looked at" | **The
|
|
49
|
+
| "Log everything you looked at" | **The case ledger, for investigations.** Evidence submitted to a case is recorded with its source skill, tool, query and fetch time. Debug's own tool calls are not written to `~/.vmware/audit.db`: none of them acts on a VMware target. |
|
|
50
50
|
|
|
51
51
|
---
|
|
52
52
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
# vmware-debug Capabilities
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Offline incident correlation. No network, no credentials, no writes to any VMware
|
|
4
|
+
system. This table covers the two stateless correlation tools; the twelve `case_*`
|
|
5
|
+
investigation-ledger tools (seven of which write, to the local ledger only) are
|
|
6
|
+
listed in `SKILL.md`, and their response sizes are not yet measured here.
|
|
4
7
|
|
|
5
8
|
| Tool | What it returns | Typical response tokens |
|
|
6
9
|
|---|---|---|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# vmware-debug CLI Reference
|
|
2
2
|
|
|
3
|
-
All commands are
|
|
3
|
+
All commands are offline (no network, no credentials). All but `mcp` are
|
|
4
|
+
read-only; `mcp` starts the MCP server, whose seven `case_*` write tools record
|
|
5
|
+
into the local case ledger.
|
|
4
6
|
|
|
5
7
|
## triage — correlate a set of collected events
|
|
6
8
|
|
|
@@ -6,7 +6,7 @@ is a pure, offline correlation engine. There is no `config.yaml` and no `.env`.
|
|
|
6
6
|
## Install
|
|
7
7
|
|
|
8
8
|
```bash
|
|
9
|
-
uv tool install vmware-debug
|
|
9
|
+
uv tool install vmware-debug==1.11.4
|
|
10
10
|
vmware-debug categories # verify it runs
|
|
11
11
|
```
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ vmware-debug categories # verify it runs
|
|
|
15
15
|
```json
|
|
16
16
|
{
|
|
17
17
|
"command": "uvx",
|
|
18
|
-
"args": ["--from", "vmware-debug", "vmware-debug-mcp"]
|
|
18
|
+
"args": ["--from", "vmware-debug==1.11.4", "vmware-debug-mcp"]
|
|
19
19
|
}
|
|
20
20
|
```
|
|
21
21
|
|
|
@@ -33,17 +33,28 @@ routes fixes to (vmware-aiops, vmware-pilot).
|
|
|
33
33
|
|
|
34
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
|
-
3. **Network** — none.
|
|
37
|
-
agent supplies.
|
|
38
|
-
4. **Writes** —
|
|
36
|
+
3. **Network** — none. The correlation tools are local pure functions over
|
|
37
|
+
event data the agent supplies; the case tools read and write local files.
|
|
38
|
+
4. **Writes** — only to the local investigation ledger under `$OPS_HOME`
|
|
39
|
+
(the seven [WRITE] `case_*` tools). Evidence, gaps, hypotheses and grade
|
|
40
|
+
history are only ever added to; `timeline.md` is regenerated from the evidence and
|
|
41
|
+
`case.json` holds the current grade and state. Nothing is written to any
|
|
42
|
+
VMware system: debug only diagnoses and recommends; remediation is routed
|
|
39
43
|
to vmware-aiops / vmware-pilot, where confirmation/approval/audit live.
|
|
44
|
+
Case data is sensitive: each case folder (`$OPS_HOME/cases/<case-id>/`, default
|
|
45
|
+
`~/.vmware/cases/`) is created owner-only (`0700`) and holds the submitted
|
|
46
|
+
evidence — host names, addresses, log and event text. There is no automatic
|
|
47
|
+
retention limit: `case_close` marks a case closed and keeps its files; delete
|
|
48
|
+
the folder to remove a case.
|
|
40
49
|
5. **No cross-skill coupling** — events arrive as plain dicts (the event
|
|
41
50
|
envelope); debug imports no other skill package at runtime.
|
|
42
51
|
6. **Environment scoping** — policy rules can scope by environment, and skills
|
|
43
52
|
that connect to a VMware estate may declare `environment:` (`production` /
|
|
44
53
|
`staging` / `lab`) per target in their own `config.yaml` as an optional label
|
|
45
54
|
an environment-scoped `deny` rule can match on. debug has no config and no
|
|
46
|
-
connection to declare one about, so it
|
|
47
|
-
|
|
55
|
+
connection to declare one about, so it registers no environment resolver —
|
|
56
|
+
it has no basis to answer for any target. Its tools do not pass through the
|
|
57
|
+
policy engine either, so no policy rule, environment-scoped or not, applies
|
|
58
|
+
to them.
|
|
48
59
|
7. **Static analysis** — `uvx bandit -r vmware_debug/` (release bar:
|
|
49
60
|
0 Medium+).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
"""Test package.
|
|
2
|
+
|
|
3
|
+
``tests/eval/`` and ``tests/eval/regression/`` were already packages while this
|
|
4
|
+
file was missing, so ``from tests.eval.regression._vsphere_event_vocabulary
|
|
5
|
+
import ...`` resolved only where the namespace-package fallback happened to
|
|
6
|
+
work. It did not on Windows, and the whole suite -- 398 tests -- failed at
|
|
7
|
+
collection. The other repos that use cross-module test imports all carry this
|
|
8
|
+
file; this one is the half-built package.
|
|
9
|
+
"""
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Session-wide sandbox: the suite must not touch the operator's real files.
|
|
2
|
+
|
|
3
|
+
Installed at *import* time, not in a fixture: a fixture runs after collection
|
|
4
|
+
has imported every test module and, with them, the package — too late to move
|
|
5
|
+
a path something already resolved.
|
|
6
|
+
|
|
7
|
+
``OPS_HOME`` moves ``vmware_policy``'s shared ``audit.db`` (and the policy,
|
|
8
|
+
budget and undo state beside it) and the case ledger under ``OPS_HOME/cases``. ``HOME`` moves anything resolved
|
|
9
|
+
from ``~``.
|
|
10
|
+
|
|
11
|
+
This repo got the sandbox on 2026-09-11, when a sibling (VMware-VDI) was found
|
|
12
|
+
writing test rows into the operator's real ``~/.vmware/audit.db`` because it
|
|
13
|
+
had none. This suite was not leaking — every case test sets ``OPS_HOME`` itself with ``monkeypatch``, so one that forgets would write into the operator's real ``~/.vmware/cases`` — but that was a property of which
|
|
14
|
+
tests exist today, not a protection. See
|
|
15
|
+
``tests/eval/regression/test_audit_isolation.py``.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
from __future__ import annotations
|
|
19
|
+
|
|
20
|
+
import atexit
|
|
21
|
+
import os
|
|
22
|
+
import shutil
|
|
23
|
+
import tempfile
|
|
24
|
+
from pathlib import Path
|
|
25
|
+
|
|
26
|
+
from vmware_policy.audit import reset_engine
|
|
27
|
+
|
|
28
|
+
# The operator's real home, captured before the redirect.
|
|
29
|
+
REAL_HOME = Path(os.path.expanduser("~"))
|
|
30
|
+
|
|
31
|
+
SANDBOX_HOME = Path(tempfile.mkdtemp(prefix="vmware-debug-tests-"))
|
|
32
|
+
|
|
33
|
+
os.environ["HOME"] = str(SANDBOX_HOME)
|
|
34
|
+
os.environ["OPS_HOME"] = str(SANDBOX_HOME / ".vmware")
|
|
35
|
+
# expanduser() consults USERPROFILE on Windows; keep every spelling pointing here.
|
|
36
|
+
os.environ["USERPROFILE"] = str(SANDBOX_HOME)
|
|
37
|
+
|
|
38
|
+
# The audit engine is a lazily built singleton bound to the path it first
|
|
39
|
+
# resolved; clear any stale binding so writes cannot go back to the real file.
|
|
40
|
+
reset_engine()
|
|
41
|
+
|
|
42
|
+
atexit.register(shutil.rmtree, SANDBOX_HOME, True)
|
|
@@ -132,13 +132,13 @@ class ScoreBoard:
|
|
|
132
132
|
),
|
|
133
133
|
"scores": merged,
|
|
134
134
|
}
|
|
135
|
-
path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n")
|
|
135
|
+
path.write_text(json.dumps(payload, indent=2, sort_keys=True) + "\n", encoding="utf-8")
|
|
136
136
|
|
|
137
137
|
|
|
138
138
|
def previous_scores(path: Path = SCORES_PATH) -> dict[str, Any]:
|
|
139
139
|
"""Load the last recorded run, or ``{}`` on a first run / unreadable file."""
|
|
140
140
|
try:
|
|
141
|
-
return json.loads(path.read_text()).get("scores", {})
|
|
141
|
+
return json.loads(path.read_text(encoding="utf-8")).get("scores", {})
|
|
142
142
|
except (OSError, ValueError):
|
|
143
143
|
return {}
|
|
144
144
|
|