Private
Public Access
test+docs(sandbox): add FR3 invariant regression tests + tech-stack note
This commit is contained in:
@@ -86,6 +86,12 @@
|
|||||||
- **Thread-Local Context Isolation:** Utilizes `threading.local()` for managing per-thread AI client context (e.g., source tier tagging), ensuring thread safety during concurrent multi-agent execution.
|
- **Thread-Local Context Isolation:** Utilizes `threading.local()` for managing per-thread AI client context (e.g., source tier tagging), ensuring thread safety during concurrent multi-agent execution.
|
||||||
- **Asynchronous Tool Execution Engine:** Refactored MCP tool dispatch and AI client loops to use `asyncio.gather` and `asyncio.to_thread`, enabling parallel execution of independent tool calls within a single AI turn to reduce latency.
|
- **Asynchronous Tool Execution Engine:** Refactored MCP tool dispatch and AI client loops to use `asyncio.gather` and `asyncio.to_thread`, enabling parallel execution of independent tool calls within a single AI turn to reduce latency.
|
||||||
|
|
||||||
|
## pyproject.toml pytest addopts (added 2026-06-19, per test_sandbox_hardening_20260619)
|
||||||
|
|
||||||
|
`[tool.pytest.ini_options].addopts = "--basetemp=tests/artifacts/_pytest_tmp"`.
|
||||||
|
|
||||||
|
**Rationale:** Per `conductor/code_styleguides/workspace_paths.md`, ALL test infrastructure paths must live under `./tests/`. pytest's `tmp_path` and `tmp_path_factory` fixtures default to `%TEMP%\pytest-of-<user>\` on Windows. This `addopts` redirects them under `./tests/` so the FR1 runtime guard's allowlist (also `./tests/`) is a single rule.
|
||||||
|
|
||||||
## Architectural Patterns
|
## Architectural Patterns
|
||||||
|
|
||||||
- **Centralized Registry Management:** Consolidation of critical application constants (e.g., `PROVIDERS`, `AGENT_TOOL_NAMES`) into `src/models.py` as a single source of truth, eliminating redundant list definitions across the UI and Controller.
|
- **Centralized Registry Management:** Consolidation of critical application constants (e.g., `PROVIDERS`, `AGENT_TOOL_NAMES`) into `src/models.py` as a single source of truth, eliminating redundant list definitions across the UI and Controller.
|
||||||
|
|||||||
@@ -192,3 +192,57 @@ def test_sloppy_py_parses_config_flag() -> None:
|
|||||||
found_set_override_call = True
|
found_set_override_call = True
|
||||||
assert found_config_arg, "sloppy.py must have a --config argparse argument"
|
assert found_config_arg, "sloppy.py must have a --config argparse argument"
|
||||||
assert found_set_override_call, "sloppy.py must call paths.set_config_override(args.config)"
|
assert found_set_override_call, "sloppy.py must call paths.set_config_override(args.config)"
|
||||||
|
|
||||||
|
|
||||||
|
def test_pyproject_toml_basetemp_is_under_tests() -> None:
|
||||||
|
"""pyproject.toml contains --basetemp=tests/artifacts/_pytest_tmp."""
|
||||||
|
pyproject = Path(__file__).resolve().parent.parent / "pyproject.toml"
|
||||||
|
text = pyproject.read_text(encoding="utf-8")
|
||||||
|
assert "--basetemp=tests/artifacts/_pytest_tmp" in text, (
|
||||||
|
"pyproject.toml must set addopts = '--basetemp=tests/artifacts/_pytest_tmp' "
|
||||||
|
"so the FR1 runtime guard's allowlist can be a single rule."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_isolate_workspace_does_not_use_tmp_path_factory_for_infra() -> None:
|
||||||
|
"""isolate_workspace fixture does not use tmp_path_factory.mktemp."""
|
||||||
|
import ast
|
||||||
|
conftest = Path(__file__).resolve().parent / "conftest.py"
|
||||||
|
tree = ast.parse(conftest.read_text(encoding="utf-8"))
|
||||||
|
for node in ast.walk(tree):
|
||||||
|
if isinstance(node, ast.FunctionDef) and node.name == "isolate_workspace":
|
||||||
|
body = node.body
|
||||||
|
if body and isinstance(body[0], ast.Expr) and isinstance(body[0].value, ast.Constant):
|
||||||
|
body = body[1:]
|
||||||
|
body_src = "\n".join(ast.unparse(stmt) for stmt in body)
|
||||||
|
assert "tmp_path_factory.mktemp" not in body_src, (
|
||||||
|
"isolate_workspace must not use tmp_path_factory.mktemp; "
|
||||||
|
"use _ISOLATION_WORKSPACE under tests/artifacts/ instead."
|
||||||
|
)
|
||||||
|
assert "_ISOLATION_WORKSPACE" in body_src, (
|
||||||
|
"isolate_workspace should reference _ISOLATION_WORKSPACE"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
raise AssertionError("isolate_workspace fixture not found in conftest.py")
|
||||||
|
|
||||||
|
|
||||||
|
def test_appcontroller_init_does_not_load_config() -> None:
|
||||||
|
"""AppController.__init__ must not call init_state() or load_config() —
|
||||||
|
fixtures apply before App.__init__; loading config in AppController.__init__
|
||||||
|
would race against the autouse isolate_workspace."""
|
||||||
|
import ast
|
||||||
|
app_controller = Path(__file__).resolve().parent.parent / "src" / "app_controller.py"
|
||||||
|
tree = ast.parse(app_controller.read_text(encoding="utf-8"))
|
||||||
|
for node in ast.walk(tree):
|
||||||
|
if isinstance(node, ast.FunctionDef) and node.name == "__init__":
|
||||||
|
src = ast.unparse(node)
|
||||||
|
assert "init_state()" not in src, (
|
||||||
|
"AppController.__init__ must not call init_state() "
|
||||||
|
"(this would trigger config reads before fixtures apply)"
|
||||||
|
)
|
||||||
|
assert "load_config()" not in src, (
|
||||||
|
"AppController.__init__ must not call load_config() "
|
||||||
|
"(this would trigger config reads before fixtures apply)"
|
||||||
|
)
|
||||||
|
return
|
||||||
|
raise AssertionError("AppController.__init__ not found")
|
||||||
Reference in New Issue
Block a user