core/tools: drop process workspace/todo globals; require bound state

This commit is contained in:
2026-07-24 16:32:33 +08:00
parent 4215a8cea0
commit 1d718582ac
19 changed files with 126 additions and 235 deletions
+8 -22
View File
@@ -1,4 +1,4 @@
"""Workspace root prefers bound InstanceState when set."""
"""Workspace policy requires bound InstanceState."""
from __future__ import annotations
@@ -16,26 +16,18 @@ from plyngent.tools.workspace import (
)
def test_get_workspace_prefers_instance(tmp_path: Path) -> None:
clear_workspace_root()
other = tmp_path / "other"
other.mkdir()
_ = set_workspace_root(tmp_path)
instance = InstanceState(workspace_root=other)
with bind_instance(instance):
assert get_workspace_root() == other.resolve()
assert get_workspace_root() == tmp_path.resolve()
clear_workspace_root()
def test_unbound_get_workspace_errors() -> None:
with pytest.raises(WorkspaceError, match="instance state is not bound"):
_ = get_workspace_root()
def test_set_workspace_mirrors_to_bound_instance(tmp_path: Path) -> None:
clear_workspace_root()
def test_set_workspace_on_bound_instance(tmp_path: Path) -> None:
instance = InstanceState()
with bind_instance(instance):
path = set_workspace_root(tmp_path)
assert instance.workspace_root == path
assert instance.workspace.root == path
assert get_workspace_root() == path
clear_workspace_root()
def test_clear_clears_bound_instance(tmp_path: Path) -> None:
@@ -44,25 +36,20 @@ def test_clear_clears_bound_instance(tmp_path: Path) -> None:
_ = set_workspace_root(tmp_path)
clear_workspace_root()
assert instance.workspace_root is None
with pytest.raises(WorkspaceError):
with pytest.raises(WorkspaceError, match="workspace root is not set"):
_ = get_workspace_root()
def test_resolve_path_accepts_instance_root_without_process_global(tmp_path: Path) -> None:
"""Instance-only workspace must be a valid resolve root (not only process global)."""
clear_workspace_root()
def test_resolve_path_uses_instance_root(tmp_path: Path) -> None:
target = tmp_path / "note.txt"
_ = target.write_text("hi", encoding="utf-8")
instance = InstanceState(workspace_root=tmp_path.resolve())
with bind_instance(instance):
resolved = resolve_path("note.txt")
assert resolved == target.resolve()
clear_workspace_root()
def test_path_denylist_uses_instance_policy(tmp_path: Path) -> None:
"""Path denylist is read from the bound instance policy bag."""
clear_workspace_root()
secret = tmp_path / "secrets"
secret.mkdir()
_ = (secret / "x.txt").write_text("no", encoding="utf-8")
@@ -70,4 +57,3 @@ def test_path_denylist_uses_instance_policy(tmp_path: Path) -> None:
instance.workspace.path_denylist = ("/secrets/",)
with bind_instance(instance), pytest.raises(WorkspaceError, match="denied by policy"):
_ = resolve_path("secrets/x.txt")
clear_workspace_root()