kin: auto-commit after pipeline
This commit is contained in:
parent
c6e53a95a1
commit
e1fe41c428
1 changed files with 125 additions and 0 deletions
|
|
@ -402,3 +402,128 @@ class TestAutoReturnIntegration:
|
|||
assert result.get("auto_returned") is not True
|
||||
task = models.get_task(conn, "P1-001")
|
||||
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} — не сброшен и не потерян"
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue