kin: KIN-021 Аудит-лог для --dangerously-skip-permissions в auto mode
This commit is contained in:
parent
67071c757d
commit
a0b0976d8d
16 changed files with 1477 additions and 14 deletions
|
|
@ -1557,3 +1557,110 @@ class TestReviewModeExecutionMode:
|
|||
assert row["execution_mode"] == "review", (
|
||||
"Регрессия KIN-055: execution_mode должен быть 'review' в SQLite после pipeline"
|
||||
)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# KIN-021: Audit log for --dangerously-skip-permissions
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
class TestAuditLogDangerousSkip:
|
||||
@patch("agents.runner._run_autocommit")
|
||||
@patch("agents.runner._run_learning_extraction")
|
||||
@patch("core.followup.generate_followups")
|
||||
@patch("agents.runner.run_hooks")
|
||||
@patch("agents.runner.subprocess.run")
|
||||
def test_audit_log_written_on_permission_retry(
|
||||
self, mock_run, mock_hooks, mock_followup, mock_learn, mock_autocommit, conn
|
||||
):
|
||||
"""При retry с --dangerously-skip-permissions записывается событие в audit_log."""
|
||||
permission_fail = _mock_claude_failure("permission denied: cannot write file")
|
||||
retry_success = _mock_claude_success({"result": "fixed"})
|
||||
|
||||
mock_run.side_effect = [permission_fail, retry_success]
|
||||
mock_hooks.return_value = []
|
||||
mock_followup.return_value = {"created": [], "pending_actions": []}
|
||||
mock_learn.return_value = {"added": 0, "skipped": 0}
|
||||
|
||||
models.update_project(conn, "vdol", execution_mode="auto_complete")
|
||||
steps = [{"role": "debugger", "brief": "find"}]
|
||||
result = run_pipeline(conn, "VDOL-001", steps)
|
||||
|
||||
assert result["success"] is True
|
||||
|
||||
# Проверяем audit_log через прямой SQL
|
||||
rows = conn.execute(
|
||||
"SELECT * FROM audit_log WHERE task_id='VDOL-001'"
|
||||
).fetchall()
|
||||
assert len(rows) == 1
|
||||
assert rows[0]["event_type"] == "dangerous_skip"
|
||||
assert rows[0]["step_id"] == "debugger"
|
||||
assert "debugger" in rows[0]["reason"]
|
||||
|
||||
@patch("agents.runner._run_autocommit")
|
||||
@patch("agents.runner._run_learning_extraction")
|
||||
@patch("core.followup.generate_followups")
|
||||
@patch("agents.runner.run_hooks")
|
||||
@patch("agents.runner.subprocess.run")
|
||||
def test_dangerously_skipped_flag_set_on_task(
|
||||
self, mock_run, mock_hooks, mock_followup, mock_learn, mock_autocommit, conn
|
||||
):
|
||||
"""tasks.dangerously_skipped=1 после retry с --dangerously-skip-permissions."""
|
||||
permission_fail = _mock_claude_failure("permission denied: cannot write file")
|
||||
retry_success = _mock_claude_success({"result": "fixed"})
|
||||
|
||||
mock_run.side_effect = [permission_fail, retry_success]
|
||||
mock_hooks.return_value = []
|
||||
mock_followup.return_value = {"created": [], "pending_actions": []}
|
||||
mock_learn.return_value = {"added": 0, "skipped": 0}
|
||||
|
||||
models.update_project(conn, "vdol", execution_mode="auto_complete")
|
||||
steps = [{"role": "debugger", "brief": "find"}]
|
||||
run_pipeline(conn, "VDOL-001", steps)
|
||||
|
||||
# Верификация через прямой SQL (минуя ORM)
|
||||
row = conn.execute(
|
||||
"SELECT dangerously_skipped FROM tasks WHERE id='VDOL-001'"
|
||||
).fetchone()
|
||||
assert row is not None
|
||||
assert row["dangerously_skipped"] == 1
|
||||
|
||||
@patch("agents.runner.run_hooks")
|
||||
@patch("agents.runner.subprocess.run")
|
||||
def test_no_audit_log_in_review_mode(self, mock_run, mock_hooks, conn):
|
||||
"""В review mode retry не происходит, audit_log остаётся пустым."""
|
||||
permission_fail = _mock_claude_failure("permission denied: cannot write file")
|
||||
mock_run.return_value = permission_fail
|
||||
mock_hooks.return_value = []
|
||||
|
||||
steps = [{"role": "debugger", "brief": "find"}]
|
||||
result = run_pipeline(conn, "VDOL-001", steps)
|
||||
|
||||
assert result["success"] is False
|
||||
rows = conn.execute(
|
||||
"SELECT * FROM audit_log WHERE task_id='VDOL-001'"
|
||||
).fetchall()
|
||||
assert len(rows) == 0
|
||||
|
||||
@patch("agents.runner._run_autocommit")
|
||||
@patch("agents.runner._run_learning_extraction")
|
||||
@patch("core.followup.generate_followups")
|
||||
@patch("agents.runner.run_hooks")
|
||||
@patch("agents.runner.subprocess.run")
|
||||
def test_audit_log_no_entry_on_normal_success(
|
||||
self, mock_run, mock_hooks, mock_followup, mock_learn, mock_autocommit, conn
|
||||
):
|
||||
"""При успешном выполнении без retry audit_log не записывается."""
|
||||
mock_run.return_value = _mock_claude_success({"result": "done"})
|
||||
mock_hooks.return_value = []
|
||||
mock_followup.return_value = {"created": [], "pending_actions": []}
|
||||
mock_learn.return_value = {"added": 0, "skipped": 0}
|
||||
|
||||
models.update_project(conn, "vdol", execution_mode="auto_complete")
|
||||
steps = [{"role": "tester", "brief": "test"}]
|
||||
result = run_pipeline(conn, "VDOL-001", steps)
|
||||
|
||||
assert result["success"] is True
|
||||
rows = conn.execute(
|
||||
"SELECT * FROM audit_log WHERE task_id='VDOL-001'"
|
||||
).fetchall()
|
||||
assert len(rows) == 0
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue