mirror of
https://github.com/rennf93/roboco.git
synced 2026-08-03 07:23:24 +02:00
feat(content): universal anti-soup guard on every agent free-text field
This commit is contained in:
@@ -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 "")
|
||||
Reference in New Issue
Block a user