vmware-debug 1.13.0__tar.gz → 1.13.1__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.
Files changed (97) hide show
  1. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/.claude-plugin/plugin.json +1 -1
  2. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/.mcp.json +1 -1
  3. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/PKG-INFO +1 -1
  4. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/RELEASE_NOTES.md +33 -0
  5. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/openclaw.plugin.json +1 -1
  6. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/package.json +1 -1
  7. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/pyproject.toml +1 -1
  8. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/server.json +2 -2
  9. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/skills/vmware-debug/SKILL.md +7 -5
  10. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/skills/vmware-debug/references/setup-guide.md +2 -2
  11. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/_scores.json +37 -37
  12. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_grading.py +9 -2
  13. vmware_debug-1.13.1/tests/test_case_grading_per_hypothesis.py +304 -0
  14. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_hypotheses.py +16 -2
  15. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/uv.lock +1 -1
  16. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/__init__.py +1 -1
  17. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/mcp_server/server.py +9 -9
  18. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/api.py +5 -1
  19. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/grading.py +120 -40
  20. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/hypotheses.py +25 -5
  21. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/rules/grading_rules.yaml +2 -0
  22. vmware_debug-1.13.0/tests/test_case_grading_per_hypothesis.py +0 -131
  23. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/.clawhubignore +0 -0
  24. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/.gitignore +0 -0
  25. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/README-CN.md +0 -0
  26. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/README.md +0 -0
  27. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/SECURITY.md +0 -0
  28. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/docs/plans/2026-08-28-investigation-layer-design.md +0 -0
  29. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/skills/vmware-debug/references/agent-guardrails.md +0 -0
  30. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/skills/vmware-debug/references/capabilities.md +0 -0
  31. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/skills/vmware-debug/references/cli-reference.md +0 -0
  32. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/skills/vmware-debug/references/event-envelope.md +0 -0
  33. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/skills/vmware-debug/references/routing.md +0 -0
  34. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/__init__.py +0 -0
  35. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/conftest.py +0 -0
  36. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/__init__.py +0 -0
  37. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/__init__.py +0 -0
  38. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/_family.py +0 -0
  39. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/_scoring.py +0 -0
  40. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/_skill.py +0 -0
  41. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/conftest.py +0 -0
  42. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/test_entity_reachability.py +0 -0
  43. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/test_error_actionability.py +0 -0
  44. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/test_tool_description_quality.py +0 -0
  45. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/capability/test_tool_manifest_budget.py +0 -0
  46. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/__init__.py +0 -0
  47. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/_vsphere_event_vocabulary.py +0 -0
  48. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_audit_isolation.py +0 -0
  49. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_capability_grader.py +0 -0
  50. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_case_id_non_ascii.py +0 -0
  51. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_case_plan_max_steps.py +0 -0
  52. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_classification_against_vsphere_vocabulary.py +0 -0
  53. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_debug_regressions.py +0 -0
  54. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_environment_resolver_isolation.py +0 -0
  55. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_every_tool_parameter_is_documented.py +0 -0
  56. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_evidence_payload_contract.py +0 -0
  57. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_host_lifecycle_classification.py +0 -0
  58. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_investigation_metrics.py +0 -0
  59. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_real_alert_titles_classify.py +0 -0
  60. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_result_envelope.py +0 -0
  61. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_skill_name_aliases.py +0 -0
  62. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_spike_resolution.py +0 -0
  63. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/eval/regression/test_tool_annotations.py +0 -0
  64. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_conclusion.py +0 -0
  65. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_evidence.py +0 -0
  66. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_ids.py +0 -0
  67. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_ledger_concurrency.py +0 -0
  68. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_plan.py +0 -0
  69. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_readiness.py +0 -0
  70. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_store.py +0 -0
  71. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_timeline_close.py +0 -0
  72. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_case_tools.py +0 -0
  73. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_knowledge.py +0 -0
  74. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_mcp_audit.py +0 -0
  75. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_safe_error_passthrough.py +0 -0
  76. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/tests/test_timeline.py +0 -0
  77. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/cli.py +0 -0
  78. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/envelope.py +0 -0
  79. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/mcp/__init__.py +0 -0
  80. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/mcp/tools.py +0 -0
  81. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/mcp_server/__init__.py +0 -0
  82. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/__init__.py +0 -0
  83. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/__init__.py +0 -0
  84. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/conclusion.py +0 -0
  85. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/evidence.py +0 -0
  86. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/ids.py +0 -0
  87. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/knowledge.py +0 -0
  88. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/model.py +0 -0
  89. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/payloads.py +0 -0
  90. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/plan.py +0 -0
  91. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/readiness.py +0 -0
  92. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/sources.py +0 -0
  93. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/store.py +0 -0
  94. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/cases/timeline.py +0 -0
  95. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/skill_names.py +0 -0
  96. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/ops/timeline.py +0 -0
  97. {vmware_debug-1.13.0 → vmware_debug-1.13.1}/vmware_debug/rules/evidence_sources.yaml +0 -0
@@ -2,7 +2,7 @@
2
2
  "$schema": "https://anthropic.com/claude-code/plugin.schema.json",
3
3
  "name": "vmware-debug",
4
4
  "displayName": "VMware Debug",
5
- "version": "1.13.0",
5
+ "version": "1.13.1",
6
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",
@@ -5,7 +5,7 @@
5
5
  "command": "uvx",
6
6
  "args": [
7
7
  "--from",
8
- "vmware-debug==1.13.0",
8
+ "vmware-debug==1.13.1",
9
9
  "vmware-debug-mcp"
10
10
  ]
11
11
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: vmware-debug
3
- Version: 1.13.0
3
+ Version: 1.13.1
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
@@ -1,3 +1,36 @@
1
+ ## v1.13.1 — a hypothesis is ruled out only by sources against it
2
+
3
+ Corrections to 1.13.0, from a second independent review on 2026-09-15. Each case below was reproduced on 1.13.0
4
+ and is now a test.
5
+
6
+ * **Exclusion counts sources per hypothesis.** 1.13.0 counted the two independent sources an exclusion needs
7
+ across the whole case. One observation against H2 plus any unrelated evidence ruled H2 out, retired the gap that
8
+ blocked H2, and promoted the case from Candidate to Probable; H1 falsified by Aria and H2 by Monitor excluded
9
+ both. A hypothesis is now ruled out only when two independent skills falsify *that* hypothesis.
10
+ * **No registered hypotheses never grades Excluded.** With a missing ledger, or a case older than the ledger,
11
+ "every hypothesis is ruled out" was true of an empty list, and the case was graded Excluded.
12
+ * **A contradicted hypothesis holds the case at Candidate.** Evidence against an open hypothesis that is not yet
13
+ enough to rule it out now holds the case where a gap that could overturn it would. Without this, the stricter
14
+ count above made a lone falsifier count for nothing, and a case kept Probable, or Confirmed, with an observation
15
+ against a hypothesis still unanswered (third review, same day).
16
+ * **A corrupt `hypotheses.md` is a reason, not a crash.** 1.13.0 handled a missing file but let a hand-edited
17
+ broken entry raise out of `case_grade`, including entries that are valid JSON but not a hypothesis (`[]`,
18
+ `null`, `{}`).
19
+ * **Falsifying evidence never counts as support.** 1.13.0 took it out of the count only when an exclusion
20
+ succeeded, so under a site rule needing three sources two falsifiers of H2 graded the case Probable.
21
+ * `case_hypotheses` loads the grading rules before registering a hypothesis, so a broken site
22
+ `grading_rules.yaml` fails the call without writing; a retry no longer registers it twice.
23
+ * **Behaviour change:** `case_hypotheses` marks a hypothesis `refuted` by the same rule as `case_grade`. With one
24
+ falsifying source it stays `open` or `blocked`; `refuted_by` still lists the item, and the first next step says
25
+ how many more sources are needed. `case_grade` reasons name each contradicted hypothesis with its evidence and
26
+ source count. A site that sets `excluded.requires_falsifying_evidence: false` never excludes, so under that
27
+ setting a contradicted hypothesis holds its case at Candidate for as long as the contradiction stands — the
28
+ grade reason says so instead of promising a rule-out that cannot happen.
29
+
30
+ Re-running the lab investigation of the same Aria alert on this code: the first observation against H2 held the
31
+ case at Candidate ("H2 is contradicted by E007 from 1 independent source(s)"), a second skill ruled H2 out, H3
32
+ went the same way, and the case ended **Probable** on H1, held below Confirmed by three open gaps.
33
+
1
34
  ## v1.13.0 — exclusion is per hypothesis
2
35
 
3
36
  Found in a real investigation of an Aria "vCenter app health is affected" alert on 2026-09-15, then corrected
@@ -11,7 +11,7 @@
11
11
  "command": "uvx",
12
12
  "args": [
13
13
  "--from",
14
- "vmware-debug==1.13.0",
14
+ "vmware-debug==1.13.1",
15
15
  "vmware-debug-mcp"
16
16
  ]
17
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zw008/vmware-debug",
3
- "version": "1.13.0",
3
+ "version": "1.13.1",
4
4
  "description": "VMware incident timeline, root-cause routing, local case ledger; no vSphere access. 14 MCP tools.",
5
5
  "private": true,
6
6
  "license": "MIT",
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "vmware-debug"
7
- version = "1.13.0"
7
+ version = "1.13.1"
8
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"
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/vmware-skills/VMware-Debug",
8
8
  "source": "github"
9
9
  },
10
- "version": "1.13.0",
10
+ "version": "1.13.1",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "pypi",
14
14
  "identifier": "vmware-debug",
15
- "version": "1.13.0",
15
+ "version": "1.13.1",
16
16
  "runtimeHint": "uvx",
17
17
  "packageArguments": [
18
18
  {
@@ -51,7 +51,7 @@ write tools touch only the local case ledger.
51
51
  ## Quick Install
52
52
 
53
53
  ```bash
54
- uv tool install vmware-debug==1.13.0
54
+ uv tool install vmware-debug==1.13.1
55
55
  vmware-debug categories # see what it can diagnose
56
56
  ```
57
57
 
@@ -175,10 +175,12 @@ ledger — submit the missing evidence, or record the gap that is blocking it.
175
175
  - **Confirmed** — that, plus a decisive item: a direct hardware diagnostic, a
176
176
  version-checked knowledge-base entry, or a vendor SR; and no gap left open
177
177
  - **Excluded** — an observation that actually rules it out. "We looked and found
178
- nothing" is a gap, not an exclusion. Exclusion is per hypothesis: the case is
179
- Excluded only when every registered hypothesis is ruled out. Otherwise
180
- `case_grade` grades what remains, counting only evidence that rules nothing
181
- out, and lists each hypothesis as `open` or `excluded` in `hypotheses`
178
+ nothing" is a gap, not an exclusion. Exclusion is per hypothesis: two
179
+ independent sources must falsify *that* hypothesis, and the case is Excluded
180
+ only when every registered hypothesis is ruled out. A hypothesis contradicted
181
+ by too few sources holds the case at Candidate. Otherwise `case_grade`
182
+ grades what remains, counting only evidence that falsifies nothing, and lists
183
+ each hypothesis as `open` or `excluded` in `hypotheses`
182
184
 
183
185
  `case_plan` is not a checklist: submit evidence and the next plan is shorter,
184
186
  lose a source and it routes around it. Its `unavailable` half is the important
@@ -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==1.13.0
9
+ uv tool install vmware-debug==1.13.1
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==1.13.0", "vmware-debug-mcp"]
18
+ "args": ["--from", "vmware-debug==1.13.1", "vmware-debug-mcp"]
19
19
  }
20
20
  ```
21
21
 
@@ -62,7 +62,7 @@
62
62
  "names_artifact",
63
63
  "states_remedy"
64
64
  ],
65
- "where": "conclusion.py:81"
65
+ "where": "conclusion.py:91"
66
66
  },
67
67
  {
68
68
  "message": "Evidence field {} is required and cannot be blank. {}",
@@ -70,7 +70,7 @@
70
70
  "names_artifact",
71
71
  "states_remedy"
72
72
  ],
73
- "where": "evidence.py:41"
73
+ "where": "evidence.py:48"
74
74
  },
75
75
  {
76
76
  "message": "Cannot read gaps.json for case {}: {}.",
@@ -78,7 +78,7 @@
78
78
  "names_artifact",
79
79
  "states_remedy"
80
80
  ],
81
- "where": "evidence.py:289"
81
+ "where": "evidence.py:308"
82
82
  },
83
83
  {
84
84
  "message": "gaps.json in case {} is not valid JSON: {}. It was hand-edited. Restore it rather than deleting it \u2014",
@@ -86,7 +86,7 @@
86
86
  "names_artifact",
87
87
  "states_remedy"
88
88
  ],
89
- "where": "evidence.py:291"
89
+ "where": "evidence.py:310"
90
90
  },
91
91
  {
92
92
  "message": "Cannot read grading_rules.yaml at {}: {}",
@@ -94,7 +94,7 @@
94
94
  "names_artifact",
95
95
  "states_remedy"
96
96
  ],
97
- "where": "grading.py:57"
97
+ "where": "grading.py:133"
98
98
  },
99
99
  {
100
100
  "message": "grading_rules.yaml at {} is not valid YAML: {}. Fix it rather than deleting it \u2014 falling back to the",
@@ -102,7 +102,7 @@
102
102
  "names_artifact",
103
103
  "states_remedy"
104
104
  ],
105
- "where": "grading.py:59"
105
+ "where": "grading.py:135"
106
106
  },
107
107
  {
108
108
  "message": "A hypothesis needs a statement \u2014 what you think happened, in one line. An unnamed hypothesis cannot ",
@@ -111,7 +111,7 @@
111
111
  "names_input",
112
112
  "states_remedy"
113
113
  ],
114
- "where": "hypotheses.py:88"
114
+ "where": "hypotheses.py:101"
115
115
  },
116
116
  {
117
117
  "message": "Cannot read hypotheses.md for case {}: {}",
@@ -119,7 +119,7 @@
119
119
  "names_artifact",
120
120
  "states_remedy"
121
121
  ],
122
- "where": "hypotheses.py:60"
122
+ "where": "hypotheses.py:66"
123
123
  },
124
124
  {
125
125
  "message": "Scope field {} is required and cannot be blank. It is what step 01 of the evidence loop produces; a ",
@@ -159,7 +159,7 @@
159
159
  "names_artifact",
160
160
  "states_remedy"
161
161
  ],
162
- "where": "store.py:81"
162
+ "where": "store.py:293"
163
163
  },
164
164
  {
165
165
  "message": "Case {} is already closed. Its record is not rewritten \u2014 reopen the question by opening a new case t",
@@ -167,7 +167,7 @@
167
167
  "names_artifact",
168
168
  "states_remedy"
169
169
  ],
170
- "where": "timeline.py:137"
170
+ "where": "timeline.py:154"
171
171
  },
172
172
  {
173
173
  "message": "Cannot read case.json for {}: {}",
@@ -175,39 +175,39 @@
175
175
  "names_artifact",
176
176
  "states_remedy"
177
177
  ],
178
- "where": "timeline.py:151"
178
+ "where": "timeline.py:168"
179
179
  }
180
180
  ],
181
181
  "per_dimension_pct": {
182
- "names_artifact": 37.2,
183
- "names_input": 95.3,
184
- "states_remedy": 62.8
182
+ "names_artifact": 40.0,
183
+ "names_input": 95.6,
184
+ "states_remedy": 64.4
185
185
  },
186
- "raise_sites": 43
186
+ "raise_sites": 45
187
187
  },
188
- "maximum": 129,
189
- "pct": 65.1,
188
+ "maximum": 135,
189
+ "pct": 66.7,
190
190
  "unit": "points",
191
- "value": 84
191
+ "value": 90
192
192
  },
193
193
  "manifest_context_headroom": {
194
194
  "detail": {
195
195
  "heaviest_tools": {
196
196
  "case_open": 521,
197
- "case_plan": 499,
197
+ "case_plan": 502,
198
198
  "case_record_gap": 410,
199
199
  "case_submit_evidence": 971,
200
200
  "incident_timeline": 521
201
201
  },
202
- "manifest_tokens": 5160,
203
- "mean_tokens_per_tool": 368.6,
202
+ "manifest_tokens": 5215,
203
+ "mean_tokens_per_tool": 372.5,
204
204
  "reference_context": 16384,
205
205
  "tool_count": 14
206
206
  },
207
207
  "maximum": 16384,
208
- "pct": 68.5,
208
+ "pct": 68.2,
209
209
  "unit": "tokens",
210
- "value": 11224
210
+ "value": 11169
211
211
  },
212
212
  "parameter_documentation_coverage": {
213
213
  "detail": {
@@ -248,7 +248,7 @@
248
248
  "ceiling": 350,
249
249
  "over_ceiling": {
250
250
  "case_open": 521,
251
- "case_plan": 499,
251
+ "case_plan": 502,
252
252
  "case_record_gap": 410,
253
253
  "case_submit_evidence": 971,
254
254
  "case_timeline": 393,
@@ -290,27 +290,27 @@
290
290
  "remedy_after_interpolation": [
291
291
  "envelope.py:126",
292
292
  "envelope.py:138",
293
- "conclusion.py:135",
294
- "conclusion.py:144",
295
- "evidence.py:179",
296
- "evidence.py:211",
297
- "evidence.py:248",
298
- "grading.py:67",
299
- "hypotheses.py:47",
300
- "hypotheses.py:70"
293
+ "conclusion.py:145",
294
+ "conclusion.py:154",
295
+ "evidence.py:186",
296
+ "evidence.py:229",
297
+ "evidence.py:264",
298
+ "grading.py:143",
299
+ "hypotheses.py:53",
300
+ "hypotheses.py:76"
301
301
  ]
302
302
  },
303
- "maximum": 28,
303
+ "maximum": 30,
304
304
  "pct": 100.0,
305
305
  "unit": "messages",
306
- "value": 28
306
+ "value": 30
307
307
  },
308
308
  "teaching_error_rate": {
309
309
  "detail": {},
310
- "maximum": 43,
311
- "pct": 34.9,
310
+ "maximum": 45,
311
+ "pct": 37.8,
312
312
  "unit": "messages",
313
- "value": 15
313
+ "value": 17
314
314
  },
315
315
  "tool_description_quality": {
316
316
  "detail": {
@@ -194,13 +194,20 @@ class TestExclusionNeedsAFalsifyingObservation:
194
194
  record_gap(case, blocking_gap())
195
195
  assert grade_case(case).grade != "excluded"
196
196
 
197
- def test_a_falsifying_observation_excludes(self, case):
197
+ def test_falsifying_observations_from_two_skills_exclude(self, case):
198
198
  record_evidence(case, evidence(skill="vmware-monitor", falsifies=("H1",)))
199
- record_evidence(case, evidence(skill="vmware-log-insight"))
199
+ record_evidence(case, evidence(skill="vmware-log-insight", falsifies=("H1",)))
200
200
  r = grade_case(case)
201
201
  assert r.grade == "excluded"
202
202
  assert any("E001" in reason for reason in r.reasons)
203
203
 
204
+ def test_one_falsifier_and_an_unrelated_source_do_not_exclude(self, case):
205
+ """The two sources have to be against the hypothesis, not anywhere in the
206
+ case (independent review, 2026-09-15)."""
207
+ record_evidence(case, evidence(skill="vmware-monitor", falsifies=("H1",)))
208
+ record_evidence(case, evidence(skill="vmware-log-insight"))
209
+ assert grade_case(case).grade != "excluded"
210
+
204
211
 
205
212
  class TestDemotion:
206
213
  def test_a_new_gap_takes_confirmed_back_down_to_probable(self, case, mounted_kb):