kin: auto-commit after pipeline

This commit is contained in:
Gros Frumos 2026-03-21 08:22:22 +02:00
parent c6e53a95a1
commit e1fe41c428

View file

@ -402,3 +402,128 @@ class TestAutoReturnIntegration:
assert result.get("auto_returned") is not True assert result.get("auto_returned") is not True
task = models.get_task(conn, "P1-001") task = models.get_task(conn, "P1-001")
assert task["status"] == "done" assert task["status"] == "done"
@patch("core.followup.generate_followups")
@patch("agents.runner.run_hooks")
@patch("agents.runner.subprocess.run")
def test_exit_condition_strategic_decision_blocks_task(
self, mock_run, mock_hooks, mock_followup, conn
):
"""exit_condition='strategic_decision' → task stays blocked, no auto-return."""
mock_hooks.return_value = []
mock_followup.return_value = {"created": [], "pending_actions": []}
mock_run.return_value = _mock_reviewer(
"changes_requested",
reason="Needs architectural decision from management",
exit_condition="strategic_decision",
)
steps = [{"role": "reviewer", "brief": "review"}]
result = run_pipeline(conn, "P1-001", steps)
assert result["success"] is False
assert result.get("auto_returned") is not True, (
"strategic_decision должен блокировать auto-return"
)
task = models.get_task(conn, "P1-001")
assert task["status"] == "blocked", (
"exit_condition='strategic_decision' → задача должна остаться blocked"
)
@patch("core.followup.generate_followups")
@patch("agents.runner.run_hooks")
@patch("agents.runner.subprocess.run")
def test_review_mode_reviewer_rejection_no_auto_return(
self, mock_run, mock_hooks, mock_followup
):
"""Scenario 2: execution_mode='review' + reviewer rejection → no auto-return.
In review mode, gate check is skipped task moves to 'review' status
waiting for human approval, never triggering auto-return.
"""
c = init_db(":memory:")
models.create_project(c, "p1", "P1", "/tmp/p1", tech_stack=["python"])
models.create_task(c, "P1-001", "p1", "Implement feature",
brief={"route_type": "feature"})
# Explicitly review mode (not auto_complete)
models.update_task(c, "P1-001", execution_mode="review")
mock_hooks.return_value = []
mock_followup.return_value = {"created": [], "pending_actions": []}
mock_run.return_value = _mock_reviewer("changes_requested",
reason="Needs work")
steps = [{"role": "reviewer", "brief": "review"}]
result = run_pipeline(c, "P1-001", steps)
c.close()
assert result.get("auto_returned") is not True, (
"В режиме review авто-возврат не должен срабатывать"
)
# In review mode the pipeline succeeds (all steps run), task waits for human
assert result["success"] is True
# ---------------------------------------------------------------------------
# Unit tests: two sequential auto-returns (decision #1082)
# ---------------------------------------------------------------------------
class TestTwoSequentialAutoReturns:
"""KIN-136: return_count increments correctly across two consecutive returns (decision #1082)."""
def test_two_sequential_auto_returns_increment_count_to_two(self, conn):
"""Two _trigger_auto_return calls → return_count = 2 (not reset, not stuck at 1)."""
with patch("agents.runner.run_pipeline") as mock_rp:
mock_rp.return_value = {"success": True, "steps_completed": 2}
# First auto-return
result1 = _trigger_auto_return(
conn, "P1-001", "p1", pipeline=None,
original_steps=[{"role": "reviewer"}],
gate_role="reviewer",
gate_reason="first rejection",
allow_write=False,
noninteractive=True,
)
assert result1["should_escalate"] is False
task_after_first = models.get_task(conn, "P1-001")
assert (task_after_first.get("return_count") or 0) == 1, (
"После первого авто-возврата return_count должен быть 1"
)
# Second auto-return (without resetting count)
result2 = _trigger_auto_return(
conn, "P1-001", "p1", pipeline=None,
original_steps=[{"role": "reviewer"}],
gate_role="reviewer",
gate_reason="second rejection",
allow_write=False,
noninteractive=True,
)
assert result2["should_escalate"] is False
task_after_second = models.get_task(conn, "P1-001")
assert (task_after_second.get("return_count") or 0) == 2, (
"После второго авто-возврата return_count должен быть 2 (не сброшен в 1)"
)
def test_return_count_not_reset_between_sequential_auto_returns(self, conn):
"""Ensures return_count accumulates across calls — cumulative, not per-run (decision #1082)."""
with patch("agents.runner.run_pipeline") as mock_rp:
mock_rp.return_value = {"success": True, "steps_completed": 2}
for call_number in range(1, _AUTO_RETURN_MAX):
_trigger_auto_return(
conn, "P1-001", "p1", pipeline=None,
original_steps=[{"role": "reviewer"}],
gate_role="reviewer",
gate_reason=f"rejection #{call_number}",
allow_write=False,
noninteractive=True,
)
task = models.get_task(conn, "P1-001")
assert (task.get("return_count") or 0) == _AUTO_RETURN_MAX - 1, (
f"После {_AUTO_RETURN_MAX - 1} авто-возвратов return_count должен быть "
f"{_AUTO_RETURN_MAX - 1} — не сброшен и не потерян"
)