feat(content): universal anti-soup guard on every agent free-text field

This commit is contained in:
Renn F
2026-06-21 04:20:07 +02:00
parent b086dc2c41
commit db74f546a3
4 changed files with 81 additions and 2 deletions
+5 -2
View File
@@ -678,7 +678,7 @@ async def test_notify_explicit_task_not_found_rejected() -> None:
env = await ca.notify(
agent_id=agent_id,
target="be-dev-1",
text="hi",
text="Please review the assembled PR before merge.",
priority="normal",
task_id=uuid4(),
)
@@ -803,7 +803,10 @@ async def test_progress_unknown_plan_step_invalid_state_lists_valid() -> None:
actions = ContentActions(_make_deps(task=task))
env = await actions.progress(
agent_id=agent_id, task_id=t.id, message="?", plan_step="bogus"
agent_id=agent_id,
task_id=t.id,
message="Finished the auth refactor step.",
plan_step="bogus",
)
body = env.as_dict()
assert body["error"] == "invalid_state", body
@@ -0,0 +1,37 @@
"""Universal anti-soup guard — no filler/placeholder text in ANY agent field.
``ContentActions._reject_soup`` is applied to every free-text content tool
(say/dm/note/progress/notify/pitch) so soup lands nowhere. It returns a
remediation Envelope (never a raw 422 — that trips the do-server circuit
breaker), or None when the text is substantive.
"""
from __future__ import annotations
import pytest
from roboco.services.gateway.content_actions import ContentActions
_guard = ContentActions._reject_soup
@pytest.mark.parametrize("soup", ["", " ", "asdf", "...", "wip", "tbd", "x", "-"])
def test_rejects_placeholders_and_filler(soup: str) -> None:
assert _guard(soup, field="message", min_chars=2) is not None
def test_accepts_substantive_text() -> None:
assert _guard("LGTM — merging after CI.", field="message", min_chars=2) is None
assert _guard("ok", field="message", min_chars=2) is None # terse but real
def test_min_chars_enforced_per_field() -> None:
# A note must be a sentence, not a fragment.
assert _guard("hi", field="note", min_chars=8) is not None
assert _guard("Reviewed the auth refactor.", field="note", min_chars=8) is None
def test_returns_remediation_envelope() -> None:
env = _guard("asdf", field="progress update", min_chars=5)
assert env is not None
assert env.error is not None
assert "progress update" in (env.remediate or "")