mirror of
https://github.com/pewdiepie-archdaemon/odysseus.git
synced 2026-09-15 12:42:21 +02:00
fix(agent): seal document approval content
This commit is contained in:
@@ -1000,6 +1000,75 @@ def test_tainted_document_edit_without_active_target_cannot_be_approved(monkeypa
|
||||
assert "ask_user" not in blocked[0]
|
||||
|
||||
|
||||
def test_tainted_document_approval_seals_current_content(monkeypatch):
|
||||
from types import SimpleNamespace
|
||||
|
||||
from src.prompt_security import untrusted_context_message
|
||||
from src.tool_approvals import document_content_digest
|
||||
|
||||
import src.agent_loop as agent_loop
|
||||
|
||||
monkeypatch.setattr(
|
||||
agent_loop,
|
||||
"get_setting",
|
||||
lambda key, default=None: default,
|
||||
raising=False,
|
||||
)
|
||||
monkeypatch.setattr(agent_loop, "get_mcp_manager", lambda: None, raising=False)
|
||||
monkeypatch.setattr(agent_loop, "estimate_tokens", lambda *args, **kwargs: 10)
|
||||
|
||||
async def fake_stream(*args, **kwargs):
|
||||
yield "data: " + json.dumps({
|
||||
"delta": "```update_document\nreplacement\n```",
|
||||
}) + "\n\n"
|
||||
yield "data: [DONE]\n\n"
|
||||
|
||||
async def should_not_execute(*args, **kwargs):
|
||||
raise AssertionError("unapproved document edit reached executor")
|
||||
|
||||
monkeypatch.setattr(agent_loop, "stream_llm_with_fallback", fake_stream)
|
||||
monkeypatch.setattr(agent_loop, "execute_tool_block", should_not_execute)
|
||||
active_document = SimpleNamespace(
|
||||
id="document-7",
|
||||
title="Draft",
|
||||
language="markdown",
|
||||
current_content="original",
|
||||
version_count=4,
|
||||
)
|
||||
events = _collect_agent_events(
|
||||
agent_loop.stream_agent_loop(
|
||||
"http://local.test/v1",
|
||||
"small-local-model",
|
||||
[
|
||||
{"role": "user", "content": "update this document"},
|
||||
untrusted_context_message("stored context", "untrusted"),
|
||||
],
|
||||
active_document=active_document,
|
||||
session_id="document-approval-session",
|
||||
owner="alice",
|
||||
max_rounds=1,
|
||||
relevant_tools={"update_document"},
|
||||
)
|
||||
)
|
||||
|
||||
approval = next(
|
||||
event["ask_user"]
|
||||
for event in events
|
||||
if event.get("ask_user", {}).get("kind") == "tool_approval"
|
||||
)
|
||||
pending = agent_loop.tool_approval_store.peek(approval["approval_id"])
|
||||
assert pending is not None
|
||||
assert pending.document_id == "document-7"
|
||||
assert pending.document_version == 4
|
||||
assert pending.document_digest == document_content_digest("original")
|
||||
agent_loop.tool_approval_store.consume(
|
||||
pending.approval_id,
|
||||
decision="deny",
|
||||
owner="alice",
|
||||
session_id="document-approval-session",
|
||||
)
|
||||
|
||||
|
||||
def test_approval_pause_does_not_trigger_teacher_takeover(monkeypatch):
|
||||
from src.prompt_security import untrusted_context_message
|
||||
|
||||
|
||||
Reference in New Issue
Block a user