diff --git a/solstone/observe/observer_cli.py b/solstone/observe/observer_cli.py index e16d010c3..6e26d8a79 100644 --- a/solstone/observe/observer_cli.py +++ b/solstone/observe/observer_cli.py @@ -30,7 +30,6 @@ from solstone.apps.observer.utils import ( get_hist_dir, list_observers, load_history, - observer_device_binding, observer_filename_prefix, pruned_segments, revoke_observer_record, @@ -62,8 +61,6 @@ def _status_label(observer: dict) -> str: """Get human-readable connection status.""" if observer.get("revoked", False): return "revoked" - if observer_device_binding(observer) is None: - return "unbound" last_seen = observer.get("last_seen") if last_seen is None: return "disconnected" @@ -477,7 +474,6 @@ def _status_all(json_output: bool = False) -> int: labels = [_status_label(r) for r in observers] connected = labels.count("connected") - unbound = labels.count("unbound") disconnected = labels.count("disconnected") revoked = labels.count("revoked") total_segments = sum( @@ -491,7 +487,6 @@ def _status_all(json_output: bool = False) -> int: { "total": len(observers), "connected": connected, - "unbound": unbound, "disconnected": disconnected, "revoked": revoked, "total_segments": total_segments, @@ -516,7 +511,6 @@ def _status_all(json_output: bool = False) -> int: print(f"Observers: {len(observers)} total") print(f" Connected: {connected}") - print(f" Unbound: {unbound}") print(f" Disconnected: {disconnected}") print(f" Revoked: {revoked}") print(f" Total segments: {total_segments}") diff --git a/solstone/think/capture_health.py b/solstone/think/capture_health.py index 1553cb23e..01d178693 100644 --- a/solstone/think/capture_health.py +++ b/solstone/think/capture_health.py @@ -35,7 +35,6 @@ def get_capture_health() -> dict: get_active_ingest_rejection, get_health_beacon, list_observers, - observer_device_binding, ) try: @@ -76,11 +75,6 @@ def get_capture_health() -> dict: "status": obs_status, } - if observer_device_binding(o) is None: - obs_status = CAPTURE_STATUS_DEGRADED - summary["status"] = obs_status - summary["unbound"] = True - rejection = get_active_ingest_rejection(o) if rejection is not None: obs_status = CAPTURE_STATUS_DEGRADED diff --git a/solstone/think/doctor.py b/solstone/think/doctor.py index 781c84142..bf943c385 100644 --- a/solstone/think/doctor.py +++ b/solstone/think/doctor.py @@ -1079,8 +1079,6 @@ def _capture_health_observer_summary(observers: list[dict]) -> str: summaries = [] for observer in observers[:3]: status = observer.get("status", "unknown") - if observer.get("unbound"): - status = f"{status} (unbound)" summaries.append(f"{observer.get('name', 'unknown')}={status}") if len(observers) > 3: summaries.append(f"+{len(observers) - 3} more") diff --git a/tests/test_capture_health.py b/tests/test_capture_health.py index ddc0a0aa2..791d101b1 100644 --- a/tests/test_capture_health.py +++ b/tests/test_capture_health.py @@ -126,7 +126,7 @@ def test_legacy_observer_not_failed(monkeypatch): assert result["observers"][0]["beacon"]["version"] == "0.3.1" -def test_unbound_observer_escalates_to_degraded(monkeypatch): +def test_unbound_observer_uses_freshness_status(monkeypatch): monkeypatch.setattr("solstone.think.capture_health.now_ms", lambda: 1000) monkeypatch.setattr( "solstone.apps.observer.utils.list_observers", @@ -135,7 +135,7 @@ def test_unbound_observer_escalates_to_degraded(monkeypatch): result = get_capture_health() - assert result["status"] == "degraded" + assert result["status"] == "active" observer = result["observers"][0] - assert observer["status"] == "degraded" - assert observer["unbound"] is True + assert observer["status"] == "active" + assert "unbound" not in observer diff --git a/tests/test_doctor.py b/tests/test_doctor.py index 730f63b50..bd0f84b83 100644 --- a/tests/test_doctor.py +++ b/tests/test_doctor.py @@ -1324,7 +1324,7 @@ class TestStaleAliasSymlink: assert "1 warnings" in capsys.readouterr().out -def test_capture_health_check_reports_unbound_degradation(doctor, monkeypatch): +def test_capture_health_check_omits_unbound_suffix(doctor, monkeypatch): monkeypatch.setattr( doctor, "get_capture_health", @@ -1338,7 +1338,8 @@ def test_capture_health_check_reports_unbound_degradation(doctor, monkeypatch): assert result.status == "warn" assert "rollup=degraded" in result.detail - assert "desktop=degraded (unbound)" in result.detail + assert "desktop=degraded" in result.detail + assert "(unbound)" not in result.detail assert result.fix == doctor._CAPTURE_HEALTH_FIX diff --git a/tests/test_observer_cli.py b/tests/test_observer_cli.py index 9b312465f..6d96922c3 100644 --- a/tests/test_observer_cli.py +++ b/tests/test_observer_cli.py @@ -759,7 +759,7 @@ def test_cmd_list_json_includes_prefix_and_status( assert "mode" not in rows["desktop"] -def test_unbound_status_surfaces_in_list_and_status( +def test_missing_binding_uses_connection_status_in_list_and_status( observer_cli_env, monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str], @@ -788,7 +788,7 @@ def test_unbound_status_surfaces_in_list_and_status( captured = capsys.readouterr() assert rc == 0 rows = {row["name"]: row for row in json.loads(captured.out)} - assert rows["unbound"]["status"] == "unbound" + assert rows["unbound"]["status"] == "connected" assert rows["revoked"]["status"] == "revoked" rc = observer_cli.cmd_list(argparse.Namespace(json_output=False)) @@ -796,7 +796,7 @@ def test_unbound_status_surfaces_in_list_and_status( captured = capsys.readouterr() assert rc == 0 assert _table_cell(captured.out, _table_row(captured.out, "unbound"), "Status") == ( - "unbound" + "connected" ) assert _table_cell(captured.out, _table_row(captured.out, "revoked"), "Status") == ( "revoked" @@ -808,7 +808,7 @@ def test_unbound_status_surfaces_in_list_and_status( captured = capsys.readouterr() assert rc == 0 - assert json.loads(captured.out)["status"] == "unbound" + assert json.loads(captured.out)["status"] == "connected" rc = observer_cli.cmd_status( argparse.Namespace(identifier="unbound", json_output=False) @@ -816,18 +816,18 @@ def test_unbound_status_surfaces_in_list_and_status( captured = capsys.readouterr() assert rc == 0 - assert " Status: unbound\n" in captured.out + assert " Status: connected\n" in captured.out rc = observer_cli.cmd_status(argparse.Namespace(identifier=None, json_output=True)) captured = capsys.readouterr() assert rc == 0 payload = json.loads(captured.out) - assert payload["unbound"] == 1 assert payload["revoked"] == 1 - assert payload["connected"] == 0 + assert payload["connected"] == 1 + assert "unbound" not in payload assert {row["name"]: row["status"] for row in payload["observers"]} == { - "unbound": "unbound", + "unbound": "connected", "revoked": "revoked", } @@ -835,9 +835,9 @@ def test_unbound_status_surfaces_in_list_and_status( captured = capsys.readouterr() assert rc == 0 - assert " Unbound: 1\n" in captured.out + assert " Unbound:" not in captured.out assert _table_cell(captured.out, _table_row(captured.out, "unbound"), "Status") == ( - "unbound" + "connected" )