mirror of
https://github.com/usestrix/strix.git
synced 2026-08-25 04:12:37 +02:00
feat(safety): workspace-file reads, approval UX, and integration hardening
Engine + integration: - Reviewer inspection now surfaces the real frozen source of an already-frozen workspace script/dependency instead of an empty string, so workspace-resident scripts resolve without a needless human defer. - Guard effectful static tools via an explicit, documented set plus the SDK's per-tool needs_approval signal; give the exec/stdin wrappers the same idempotency guard as their sibling wrappers. - Centralize DEFAULT_SAFETY_MODE and share one resume safety-mode rule between the CLI and runner so the two cannot drift; type InspectionContext.runner, reuse RUNTIME_STATE_DIR_NAME, and drop a dead workdir parameter and a write-only field. TUI approval experience: - Approve All drops the run into dangerous mode: it approves the pending call and turns review off for the rest of the run, with a standing "review off" status flag. - The status row shows the owning agent as paused while it waits on a decision. - Redesigned prompt: a risk + tool header, a collapsible command/reason preview that expands (e) and scrolls, and no internal digest, agent, or request ids. Full Python (1138) and Go suites, ruff, and mypy strix/ pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
41b7b4f392
commit
ccbd8c7b58
@@ -115,6 +115,32 @@ async def receive_initial_state(connection: socket.socket) -> None:
|
||||
complete.add(payload["collection"])
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_state_frame_can_carry_many_concurrent_approvals() -> None:
|
||||
controller = TuiController(args())
|
||||
requests = [
|
||||
asyncio.create_task(
|
||||
controller.safety_approval_callback(
|
||||
{
|
||||
"request_id": f"approval-{index}",
|
||||
"agent_id": f"agent-{index}",
|
||||
"action": "x" * 500,
|
||||
"reason": "y" * 500,
|
||||
}
|
||||
)
|
||||
)
|
||||
for index in range(80)
|
||||
]
|
||||
await asyncio.sleep(0)
|
||||
server = TuiBackendServer(controller)
|
||||
|
||||
encoded = server._encode(envelope("state", {"revision": 1, "state": controller.snapshot()}))
|
||||
|
||||
assert len(encoded) > MAX_COMMAND_BYTES
|
||||
await controller.cancel_pending_safety_approvals()
|
||||
assert set(await asyncio.gather(*requests)) == {"cancelled"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_server_requires_ready_before_state_or_commands() -> None:
|
||||
backend, child = socket.socketpair()
|
||||
|
||||
Reference in New Issue
Block a user