From 35f49db8ed8a8bfae9c6cdbfdc4f9568e44469d8 Mon Sep 17 00:00:00 2001 From: Jer Miller Date: Mon, 6 Jul 2026 23:18:44 -0600 Subject: [PATCH] fix(health): keep thin health summary imports clean --- CHANGELOG.md | 6 ++++ packages/solstone-journal-cuda/pyproject.toml | 4 +-- packages/solstone-journal/pyproject.toml | 4 +-- pyproject.toml | 2 +- solstone/think/tools/health.py | 25 +++++++++++++-- tests/test_surfaces_health.py | 32 +++++++++++++++++++ uv.lock | 6 ++-- 7 files changed, 68 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb0b5271b..1c0ad3f1d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,12 @@ All notable changes to solstone (the Python package) will be documented in this Format adapted from [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), aligned with `cmo/brand/changelog-voice.md`. +## [0.8.1] - 2026-07-07 + +### Fixed + +- sol-only installs now render provider readiness in `sol call health summary` without importing journal-only model setup code. + ## [0.8.0] - 2026-07-07 ### Added diff --git a/packages/solstone-journal-cuda/pyproject.toml b/packages/solstone-journal-cuda/pyproject.toml index ca83025ae..ad5ec9911 100644 --- a/packages/solstone-journal-cuda/pyproject.toml +++ b/packages/solstone-journal-cuda/pyproject.toml @@ -9,10 +9,10 @@ build-backend = "setuptools.build_meta" name = "solstone-journal-cuda" description = "the journal with the NVIDIA CUDA transcription runtime — the memory sol keeps for you, on a computer you choose. Installs the journal service and includes sol." readme = {text = "the journal with the NVIDIA CUDA transcription runtime — the memory sol keeps for you, on a computer you choose. Installs the journal service and includes sol.\n\n pip install solstone-journal-cuda\n\nSee https://github.com/solpbc/solstone-journal.", content-type = "text/markdown"} -version = "0.8.0" +version = "0.8.1" requires-python = ">=3.12" dependencies = [ - "solstone[journal-host]==0.8.0", + "solstone[journal-host]==0.8.1", # GPU ONNX runtime (NVIDIA / Linux x86_64): the GPU wheel supplies the # `onnxruntime` namespace (incl. CPU providers) for VAD, diarization, and # WeSpeaker. Never co-install with the CPU `solstone-journal` leaf — both own diff --git a/packages/solstone-journal/pyproject.toml b/packages/solstone-journal/pyproject.toml index 5221da524..c48bcf0b5 100644 --- a/packages/solstone-journal/pyproject.toml +++ b/packages/solstone-journal/pyproject.toml @@ -9,10 +9,10 @@ build-backend = "setuptools.build_meta" name = "solstone-journal" description = "the journal — the memory sol keeps for you, on a computer you choose. Installs the journal service and includes sol." readme = {text = "the journal — the memory sol keeps for you, on a computer you choose. Installs the journal service and includes sol.\n\n pip install solstone-journal\n\nSee https://github.com/solpbc/solstone-journal.", content-type = "text/markdown"} -version = "0.8.0" +version = "0.8.1" requires-python = ">=3.12" dependencies = [ - "solstone[journal-host]==0.8.0", + "solstone[journal-host]==0.8.1", # CPU ONNX runtime: covers VAD, diarization, and the WeSpeaker embedder; # !=1.24.1 across the board (known-bad wheel). "onnxruntime>=1.20.0,!=1.24.1", diff --git a/pyproject.toml b/pyproject.toml index 893ea2074..cb7dfd9e6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "solstone" -version = "0.8.0" +version = "0.8.1" description = "Navigate Life Intelligently" readme = "README.md" requires-python = ">=3.12" diff --git a/solstone/think/tools/health.py b/solstone/think/tools/health.py index a43f43349..639e21a53 100644 --- a/solstone/think/tools/health.py +++ b/solstone/think/tools/health.py @@ -34,9 +34,28 @@ def _dash(value: object) -> object: return "—" if value is None else value -def _render_summary(report: dict) -> None: - from solstone.convey.readiness_snapshot import highest_severity_group +_READINESS_SEVERITY_RANK = { + "ok": 0, + "neutral": 1, + "attention": 2, + "blocker": 3, +} + + +def _highest_severity_group(snapshot: dict) -> dict | None: + groups = snapshot.get("groups") or [] + if not groups: + return None + return max( + groups, + key=lambda group: ( + _READINESS_SEVERITY_RANK.get(group.get("severity", ""), -1), + group.get("semantic_key", ""), + ), + ) + +def _render_summary(report: dict) -> None: capture = report["capture_health"] synthesis = report["synthesis_health"] consumer_signal = report["consumer_signal"] @@ -110,7 +129,7 @@ def _render_summary(report: dict) -> None: summary = snap.get("summary", {}) active = summary.get("active_groups", 0) group_word = "provider group" if active == 1 else "provider groups" - top = highest_severity_group(snap) + top = _highest_severity_group(snap) if top is not None: typer.echo(f" [{top.get('severity')}] {top.get('summary')}") typer.echo(f" {active} {group_word} need attention") diff --git a/tests/test_surfaces_health.py b/tests/test_surfaces_health.py index 0c5b711fd..fdf6e8354 100644 --- a/tests/test_surfaces_health.py +++ b/tests/test_surfaces_health.py @@ -3,6 +3,7 @@ from __future__ import annotations +import builtins import json import os import re @@ -1613,6 +1614,37 @@ def test_human_block_blocked(tmp_path, monkeypatch): assert "blocked_reason_code" not in result.stdout +def test_human_block_renderer_stays_thin(tmp_path, monkeypatch): + _configure_env(tmp_path, monkeypatch) + _set_now(monkeypatch, _utc_dt("20260410")) + _minimal_facet_tree(tmp_path) + monkeypatch.setattr( + health_surface, "read_segment_backlog", lambda: _segment_backlog({}) + ) + monkeypatch.setattr( + health_surface, + "build_readiness_snapshot", + _blocked_readiness_snapshot, + ) + _patch_health_cli_client(tmp_path, monkeypatch) + + from solstone.think.call import call_app + + real_import = builtins.__import__ + + def guarded_import(name, globals=None, locals=None, fromlist=(), level=0): + if name == "solstone.convey.readiness_snapshot": + raise AssertionError("health renderer imported journal readiness builder") + return real_import(name, globals, locals, fromlist, level) + + monkeypatch.setattr(builtins, "__import__", guarded_import) + + result = _RUNNER.invoke(call_app, ["health", "summary"]) + + assert result.exit_code == 0 + assert "Distinctive provider blocker summary" in result.stdout + + def test_human_block_unavailable(tmp_path, monkeypatch): _configure_env(tmp_path, monkeypatch) _set_now(monkeypatch, _utc_dt("20260410")) diff --git a/uv.lock b/uv.lock index e4a47d56a..2a62b1dff 100644 --- a/uv.lock +++ b/uv.lock @@ -4282,7 +4282,7 @@ wheels = [ [[package]] name = "solstone" -version = "0.8.0" +version = "0.8.1" source = { editable = "." } dependencies = [ { name = "argon2-cffi" }, @@ -4446,7 +4446,7 @@ journal-cuda = [{ name = "solstone-journal-cuda", editable = "packages/solstone- [[package]] name = "solstone-journal" -version = "0.8.0" +version = "0.8.1" source = { editable = "packages/solstone-journal" } dependencies = [ { name = "onnxruntime" }, @@ -4462,7 +4462,7 @@ requires-dist = [ [[package]] name = "solstone-journal-cuda" -version = "0.8.0" +version = "0.8.1" source = { editable = "packages/solstone-journal-cuda" } dependencies = [ { name = "nvidia-cublas-cu12" }, -- 2.51.2