Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions loopx/extensions/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,11 +478,10 @@ def extension_status(
"enabled": bool(entry.get("enabled")),
"active_revision": entry.get("active_revision"),
"rollback_available": bool(entry.get("rollback_revision")),
# Readiness is the same predicate the catalog and dispatch use:
# a stale proof under an incompatible API is not "verified".
"doctor_verified": bool(entry.get("enabled"))
and _active_manifest_incompatibility(entry) is None
and _verified_entrypoint(entry) is not None,
# A proof must resolve the exact active revision before its
# compatibility is meaningful; older unrevisioned state stays
# visible but unverified.
"doctor_verified": _status_doctor_verified(entry),
"revision_count": len(entry.get("revisions") or []),
}
for entry in visible
Expand Down Expand Up @@ -669,6 +668,16 @@ def _active_manifest_incompatibility(entry: Mapping[str, Any]) -> str | None:
)


def _status_doctor_verified(entry: Mapping[str, Any]) -> bool:
"""Require a revision-bound doctor proof before resolving compatibility."""

return (
bool(entry.get("enabled"))
and _verified_entrypoint(entry) is not None
and _active_manifest_incompatibility(entry) is None
)


def extension_catalog_entries(
extension_manifest_paths: Iterable[str | Path] = (),
*,
Expand Down
7 changes: 6 additions & 1 deletion tests/test_local_state_migration.py
Original file line number Diff line number Diff line change
Expand Up @@ -614,7 +614,12 @@ def test_extension_cli_keeps_legacy_machine_state_without_a_global_registry(tmp_
"schema_version": "loopx_extension_state_v0",
"extensions": {"example": {"id": "example", "enabled": True}},
})
assert _list_extensions(source.parents[1])[0]["id"] == "example"
listed = _list_extensions(source.parents[1])[0]
assert listed["id"] == "example"
assert listed["enabled"] is True
assert listed["active_revision"] is None
assert listed["revision_count"] == 0
assert listed["doctor_verified"] is False
assert _extension_cli(source.parents[1], "disable", "example", "--execute")["changed"]
assert _read(source / "extensions" / "state.json")["extensions"]["example"]["enabled"] is False
assert not target.exists()
Expand Down
Loading