cluxion-agentplugin-preprocessing 0.3.6__tar.gz → 0.3.7__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 (90) hide show
  1. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/PKG-INFO +1 -1
  2. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/pyproject.toml +1 -1
  3. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/__init__.py +1 -1
  4. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/doctor/probes.py +150 -1
  5. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/test_doctor.py +20 -5
  6. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/.github/profile/README.md +0 -0
  7. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/.gitignore +0 -0
  8. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/Docs/README.md +0 -0
  9. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/LICENSE +0 -0
  10. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/README.md +0 -0
  11. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/adapters/claude/.claude-plugin/plugin.json +0 -0
  12. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/adapters/claude/skills/preprocess/SKILL.md +0 -0
  13. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/adapters/codex/config-snippet.toml +0 -0
  14. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/cluxion-Docs/README.md +0 -0
  15. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/cluxion-Docs/architecture.md +0 -0
  16. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/cluxion-Docs/harness-logic.md +0 -0
  17. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/cluxion-Docs/honesty-preprocessing.md +0 -0
  18. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/cluxion-Docs/install-and-operations.md +0 -0
  19. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/cluxion-Docs/security.md +0 -0
  20. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/Cargo.lock +0 -0
  21. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/Cargo.toml +0 -0
  22. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/pyproject.toml +0 -0
  23. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/src/context.rs +0 -0
  24. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/src/dispatch.rs +0 -0
  25. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/src/guard.rs +0 -0
  26. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/src/lib.rs +0 -0
  27. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/src/main.rs +0 -0
  28. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/src/queue.rs +0 -0
  29. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/rust/cluxion_queue/src/types.rs +0 -0
  30. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/cli.py +0 -0
  31. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/doctor/__init__.py +0 -0
  32. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/doctor/catalog.json +0 -0
  33. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/doctor/framework.py +0 -0
  34. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/guard_watch.py +0 -0
  35. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/hermes_config.py +0 -0
  36. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/plugin.py +0 -0
  37. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/plugin.yaml +0 -0
  38. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/runner.py +0 -0
  39. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_agentplugin_preprocessing/schemas.py +0 -0
  40. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/__init__.py +0 -0
  41. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/__main__.py +0 -0
  42. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/adapters/__init__.py +0 -0
  43. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/adapters/contract.py +0 -0
  44. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/adapters/grok_build.py +0 -0
  45. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/adapters/hermes.py +0 -0
  46. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/adapters/spec.py +0 -0
  47. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/bootstrap.py +0 -0
  48. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/cli.py +0 -0
  49. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/__init__.py +0 -0
  50. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/clarification.py +0 -0
  51. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/context_compress.py +0 -0
  52. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/dispatch_store.py +0 -0
  53. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/harness.py +0 -0
  54. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/intent.py +0 -0
  55. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/ledger.py +0 -0
  56. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/ledger_codec.py +0 -0
  57. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/plan_codec.py +0 -0
  58. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/preprocess.py +0 -0
  59. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/types.py +0 -0
  60. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/core/work_queue.py +0 -0
  61. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/guard_daemon_host.py +0 -0
  62. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/models/__init__.py +0 -0
  63. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/models/supervisor.py +0 -0
  64. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/models/vllm_mlx.py +0 -0
  65. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/resources/__init__.py +0 -0
  66. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/resources/guard_bridge.py +0 -0
  67. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/resources/py_queue.py +0 -0
  68. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/resources/queue_bridge.py +0 -0
  69. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/resources/rust_bridge.py +0 -0
  70. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/web/__init__.py +0 -0
  71. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/src/cluxion_runtime/web/browser_bridge.py +0 -0
  72. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_browser_bridge.py +0 -0
  73. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_clarification.py +0 -0
  74. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_cluxion_runtime_spine.py +0 -0
  75. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_context_compress.py +0 -0
  76. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_contract.py +0 -0
  77. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_dispatch_store.py +0 -0
  78. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_guard.py +0 -0
  79. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_ledger.py +0 -0
  80. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_py_queue_concurrency.py +0 -0
  81. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_queue_backends.py +0 -0
  82. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_runtime_adapter_cli.py +0 -0
  83. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_rust_queue.py +0 -0
  84. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/runtime/test_supervisor.py +0 -0
  85. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/test_bootstrap.py +0 -0
  86. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/test_guard_watch.py +0 -0
  87. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/test_hermes_config.py +0 -0
  88. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/test_packaging_policy.py +0 -0
  89. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/test_plugin.py +0 -0
  90. {cluxion_agentplugin_preprocessing-0.3.6 → cluxion_agentplugin_preprocessing-0.3.7}/tests/test_runner.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: cluxion-agentplugin-preprocessing
3
- Version: 0.3.6
3
+ Version: 0.3.7
4
4
  Summary: Universal agent plugin for Cluxion preprocessing, honesty contracts, clarification, Rust work queue, and resource-aware harness handoff.
5
5
  Project-URL: Homepage, https://github.com/cluxion/cluxion-Agentplugin-preprocessing
6
6
  Project-URL: Repository, https://github.com/cluxion/cluxion-Agentplugin-preprocessing
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "cluxion-agentplugin-preprocessing"
7
- version = "0.3.6"
7
+ version = "0.3.7"
8
8
  description = "Universal agent plugin for Cluxion preprocessing, honesty contracts, clarification, Rust work queue, and resource-aware harness handoff."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -2,6 +2,6 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- __version__ = "0.3.6"
5
+ __version__ = "0.3.7"
6
6
 
7
7
  __all__ = ["__version__"]
@@ -3,7 +3,12 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import importlib.metadata
6
+ import importlib.util
7
+ import json as _json
8
+ import os
6
9
  import shutil
10
+ import sys
11
+ import tempfile
7
12
  from collections.abc import Callable
8
13
 
9
14
  from .framework import DoctorContext
@@ -96,7 +101,7 @@ def native_module_importable(ctx: DoctorContext) -> tuple[str, str]:
96
101
  return "pass", "imported (native backend available)"
97
102
  return "warn", "imported but expected symbols missing"
98
103
  except Exception:
99
- return "warn", "native missing \u2192 using fallback (slower)"
104
+ return "warn", "native missing using fallback (slower)"
100
105
 
101
106
 
102
107
  # plugin-specific probes (deterministic ones only)
@@ -174,4 +179,148 @@ def handler_exception_coverage(ctx: DoctorContext) -> tuple[str, str]:
174
179
  return "skip", f"cannot invoke guard: {e}"
175
180
 
176
181
 
182
+ def _safe_read_hermes_config():
183
+ try:
184
+ import yaml
185
+ cfg_path = os.path.expanduser("~/.hermes/config.yaml")
186
+ if not os.path.exists(cfg_path):
187
+ return None, "absent"
188
+ with open(cfg_path, encoding="utf-8") as f:
189
+ data = yaml.safe_load(f) or {}
190
+ return data, "ok"
191
+ except Exception as e:
192
+ return None, f"read_error:{type(e).__name__}"
193
+
194
+
195
+ @_register("psutil_importable")
196
+ def psutil_importable(ctx: DoctorContext) -> tuple[str, str]:
197
+ try:
198
+ import psutil
199
+ _ = psutil.virtual_memory()
200
+ return "pass", "importable"
201
+ except ImportError:
202
+ return "fail", "psutil not installed"
203
+ except Exception as e:
204
+ return "skip", f"uncertainty: {type(e).__name__}"
205
+
206
+
207
+ @_register("pyyaml_importable")
208
+ def pyyaml_importable(ctx: DoctorContext) -> tuple[str, str]:
209
+ try:
210
+ import yaml
211
+ yaml.safe_load("test: 1")
212
+ return "pass", "importable"
213
+ except ImportError:
214
+ return "fail", "PyYAML not installed"
215
+ except Exception as e:
216
+ return "skip", f"uncertainty: {type(e).__name__}"
217
+
218
+
219
+ @_register("fcntl_available_on_posix")
220
+ def fcntl_available_on_posix(ctx: DoctorContext) -> tuple[str, str]:
221
+ if os.name != "posix":
222
+ return "skip", "non-POSIX (Windows)"
223
+ try:
224
+ import fcntl
225
+ # real check: lock a temp file
226
+ with tempfile.NamedTemporaryFile(delete=False) as tf:
227
+ tf_path = tf.name
228
+ try:
229
+ with open(tf_path, "a+b") as f:
230
+ fcntl.flock(f.fileno(), fcntl.LOCK_EX)
231
+ fcntl.flock(f.fileno(), fcntl.LOCK_UN)
232
+ return "pass", "fcntl works on POSIX"
233
+ finally:
234
+ os.unlink(tf_path)
235
+ except Exception as e:
236
+ return "skip", f"fcntl issue: {type(e).__name__}"
237
+
238
+
239
+ @_register("playwright_optional_available")
240
+ def playwright_optional_available(ctx: DoctorContext) -> tuple[str, str]:
241
+ if importlib.util.find_spec("playwright") is not None:
242
+ return "pass", "importable"
243
+ return "warn", "optional, not installed"
244
+
245
+
246
+ @_register("abi3_wheel_compatible")
247
+ def abi3_wheel_compatible(ctx: DoctorContext) -> tuple[str, str]:
248
+ # since requires-python >=3.11 the check is always pass
249
+ return "pass", f"Python {sys.version_info.major}.{sys.version_info.minor} >= 3.11 abi3 floor"
250
+
251
+
252
+ @_register("sqlite_wal_mode_compatible")
253
+ def sqlite_wal_mode_compatible(ctx: DoctorContext) -> tuple[str, str]:
254
+ try:
255
+ import sqlite3
256
+ conn = sqlite3.connect(":memory:")
257
+ try:
258
+ mode = conn.execute("PRAGMA journal_mode=WAL").fetchone()[0]
259
+ ver = sqlite3.sqlite_version
260
+ if str(mode).lower() == "wal":
261
+ return "pass", f"wal supported (sqlite {ver})"
262
+ return "warn", f"got {mode} (sqlite {ver})"
263
+ finally:
264
+ conn.close()
265
+ except Exception as e:
266
+ return "skip", f"uncertainty: {type(e).__name__}"
267
+
268
+
269
+ @_register("json_serialization_deterministic")
270
+ def json_serialization_deterministic(ctx: DoctorContext) -> tuple[str, str]:
271
+ try:
272
+ d = {"z": 1, "a": 2, "nested": {"b": 3}}
273
+ j1 = _json.dumps(d, sort_keys=True, separators=(",", ":"))
274
+ j2 = _json.dumps(d, sort_keys=True, separators=(",", ":"))
275
+ if j1 == j2:
276
+ return "pass", "roundtrip bytes equal"
277
+ return "fail", "non-deterministic"
278
+ except Exception as e:
279
+ return "skip", f"uncertainty: {type(e).__name__}"
280
+
281
+
282
+ @_register("hermes_plugin_enabled")
283
+ def hermes_plugin_enabled(ctx: DoctorContext) -> tuple[str, str]:
284
+ data, status = _safe_read_hermes_config()
285
+ if status != "ok":
286
+ return "skip", f"config not present: {status}"
287
+ try:
288
+ plugins = (data or {}).get("plugins", {}) or {}
289
+ enabled = plugins.get("enabled", []) or []
290
+ disabled = plugins.get("disabled", []) or []
291
+ names = ["cluxion-agentplugin-preprocessing", "hermes-cluxion"]
292
+ for n in names:
293
+ if n in enabled and n not in disabled:
294
+ return "pass", f"{n} in enabled"
295
+ if any(n in enabled for n in names):
296
+ return "warn", "present but also disabled?"
297
+ return "warn", "not in plugins.enabled"
298
+ except Exception as e:
299
+ return "skip", f"uncertainty: {type(e).__name__}"
300
+
301
+
302
+ @_register("env_var_consistency")
303
+ def env_var_consistency(ctx: DoctorContext) -> tuple[str, str]:
304
+ try:
305
+ known = [
306
+ "CLUXION_QUEUE_STORE_DIR",
307
+ "CLUXION_PREPROCESS_DISPATCH_DIR",
308
+ "CLUXION_QUEUE_BACKEND",
309
+ ]
310
+ issues = []
311
+ for var in known:
312
+ val = os.environ.get(var)
313
+ if val and "DIR" in var:
314
+ try:
315
+ p = os.path.expanduser(val)
316
+ os.makedirs(p, exist_ok=True)
317
+ except Exception:
318
+ issues.append(f"{var}=invalid_path")
319
+ if issues:
320
+ return "warn", ";".join(issues)
321
+ return "pass", "defaults or valid"
322
+ except Exception as e:
323
+ return "skip", f"uncertainty: {type(e).__name__}"
324
+
325
+
177
326
  # note: other checks in catalog will be reported as skip (no probe)
@@ -24,7 +24,7 @@ def test_run_doctor_returns_result_and_deterministic():
24
24
  catalog_path=cat,
25
25
  probes=PROBES,
26
26
  plugin="preprocessing",
27
- version="0.3.6",
27
+ version="0.3.7",
28
28
  )
29
29
  assert isinstance(r1, DoctorResult)
30
30
  j1 = render_json(r1)
@@ -33,7 +33,7 @@ def test_run_doctor_returns_result_and_deterministic():
33
33
  catalog_path=cat,
34
34
  probes=PROBES,
35
35
  plugin="preprocessing",
36
- version="0.3.6",
36
+ version="0.3.7",
37
37
  )
38
38
  j2 = render_json(r2)
39
39
  assert j1 == j2 # byte identical
@@ -49,7 +49,7 @@ def test_cross_cutting_checks_present():
49
49
  catalog_path=cat,
50
50
  probes=PROBES,
51
51
  plugin="preprocessing",
52
- version="0.3.6",
52
+ version="0.3.7",
53
53
  )
54
54
  statuses = {c.check_id: c.status for c in result.checks}
55
55
  for key in ("hermes_on_path", "entry_point_registered", "toolset_valid"):
@@ -57,6 +57,21 @@ def test_cross_cutting_checks_present():
57
57
  assert statuses[key] in ("pass", "warn", "fail", "skip")
58
58
 
59
59
 
60
+ def test_new_probes_non_skip():
61
+ cat = _catalog_path()
62
+ result = run_doctor(
63
+ cwd=Path.cwd(),
64
+ catalog_path=cat,
65
+ probes=PROBES,
66
+ plugin="preprocessing",
67
+ version="0.3.7",
68
+ )
69
+ statuses = {c.check_id: c.status for c in result.checks}
70
+ for key in ("psutil_importable", "json_serialization_deterministic"):
71
+ assert key in statuses
72
+ assert statuses[key] in ("pass", "warn", "fail") # non-skip
73
+
74
+
60
75
  def test_probe_exception_becomes_fail():
61
76
  def bad_probe(ctx):
62
77
  raise RuntimeError("boom")
@@ -66,7 +81,7 @@ def test_probe_exception_becomes_fail():
66
81
  catalog_path=_catalog_path(),
67
82
  probes={"hermes_on_path": bad_probe},
68
83
  plugin="preprocessing",
69
- version="0.3.6",
84
+ version="0.3.7",
70
85
  )
71
86
  statuses = {c.check_id: c.status for c in result.checks}
72
87
  assert statuses["hermes_on_path"] == "fail"
@@ -78,5 +93,5 @@ def test_warn_only_is_ok():
78
93
  checks = (
79
94
  CheckResult(check_id="x", category="c", severity="medium", status="warn", detail="w"),
80
95
  )
81
- r = DoctorResult(plugin="p", version="0.3.6", checks=checks)
96
+ r = DoctorResult(plugin="p", version="0.3.7", checks=checks)
82
97
  assert r.ok is True