{$t.dataset_review?.clarification?.options_title}
++ Следующий шаг: выбрать вариант, дать собственный ответ или пометить вопрос для expert review. +
diff --git a/.kilo/agents/complexity-auditor.md b/.kilo/agents/complexity-auditor.md index be1255b1..485002b4 100644 --- a/.kilo/agents/complexity-auditor.md +++ b/.kilo/agents/complexity-auditor.md @@ -5,7 +5,7 @@ model: github-copilot/claude-opus-4.6 temperature: 0.0 permission: edit: deny - bash: ask + bash: allow browser: deny task: repair-worker: allow diff --git a/backend/src/api/routes/__tests__/conftest.py b/backend/src/api/routes/__tests__/conftest.py index eac3843f..3fc1280d 100644 --- a/backend/src/api/routes/__tests__/conftest.py +++ b/backend/src/api/routes/__tests__/conftest.py @@ -6,8 +6,10 @@ class FakeQuery: """Shared chainable query stub for route tests. - Warning: predicate arguments passed to filter() are recorded only for inspection - and are not evaluated; result sets remain predicate-blind. + WARNING: filter() is predicate-blind — all ownership and permission filters are + ignored. Tests using FakeQuery cannot verify scoped data access. This is a + known limitation; do not use for permission-sensitive test paths without a + spec-guarded replacement. """ def __init__(self, rows): diff --git a/backend/src/api/routes/__tests__/test_dataset_review_api.py b/backend/src/api/routes/__tests__/test_dataset_review_api.py index 0ac7c5ef..0c376c54 100644 --- a/backend/src/api/routes/__tests__/test_dataset_review_api.py +++ b/backend/src/api/routes/__tests__/test_dataset_review_api.py @@ -256,6 +256,11 @@ def _make_us2_session(): # [DEF:_make_us3_session:Function] # @RELATION: BINDS_TO -> DatasetReviewApiTests def _make_us3_session(): + """Fake session factory for US3 flow tests. + + `imported_filter` and `template_variable` are bare MagicMocks without spec; + ORM attribute access is unchecked. + """ now = datetime.now(timezone.utc) session = _make_session() session.readiness_state = ReadinessState.MAPPING_REVIEW_NEEDED @@ -587,6 +592,8 @@ def test_orchestrator_start_session_preserves_partial_recovery( orchestrator = DatasetReviewOrchestrator( repository=repository, config_manager=dataset_review_api_dependencies["config_manager"], + # WARNING: task_manager=None — all async task dispatch paths are bypassed. + # Task dispatch failures are invisible to this test. task_manager=None, ) @@ -653,6 +660,8 @@ def test_orchestrator_start_session_bootstraps_recovery_state( orchestrator = DatasetReviewOrchestrator( repository=repository, config_manager=dataset_review_api_dependencies["config_manager"], + # WARNING: task_manager=None — all async task dispatch paths are bypassed. + # Task dispatch failures are invisible to this test. task_manager=None, ) @@ -1255,6 +1264,8 @@ def test_execution_snapshot_includes_recovered_imported_filters_without_template orchestrator = DatasetReviewOrchestrator( repository=repository, config_manager=dataset_review_api_dependencies["config_manager"], + # WARNING: task_manager=None — all async task dispatch paths are bypassed. + # Task dispatch failures are invisible to this test. task_manager=None, ) session = _make_preview_ready_session() @@ -1326,6 +1337,8 @@ def test_execution_snapshot_preserves_mapped_template_variables_and_filter_conte orchestrator = DatasetReviewOrchestrator( repository=repository, config_manager=dataset_review_api_dependencies["config_manager"], + # WARNING: task_manager=None — all async task dispatch paths are bypassed. + # Task dispatch failures are invisible to this test. task_manager=None, ) session = _make_preview_ready_session() @@ -1363,6 +1376,8 @@ def test_execution_snapshot_skips_partial_imported_filters_without_values( orchestrator = DatasetReviewOrchestrator( repository=repository, config_manager=dataset_review_api_dependencies["config_manager"], + # WARNING: task_manager=None — all async task dispatch paths are bypassed. + # Task dispatch failures are invisible to this test. task_manager=None, ) session = _make_preview_ready_session() diff --git a/backend/src/api/routes/__tests__/test_datasets.py b/backend/src/api/routes/__tests__/test_datasets.py index 9b616c4a..8aeb798e 100644 --- a/backend/src/api/routes/__tests__/test_datasets.py +++ b/backend/src/api/routes/__tests__/test_datasets.py @@ -31,6 +31,10 @@ mock_user.roles.append(admin_role) @pytest.fixture(autouse=True) def mock_deps(): + """Bare MagicMock — no spec guards. All service method calls succeed silently. + + Authorization, data integrity, and error paths are invisible to this fixture. + """ # @INVARIANT: unconstrained mock — no spec= enforced; attribute typos will silently pass config_manager = MagicMock() # @INVARIANT: unconstrained mock — no spec= enforced; attribute typos will silently pass diff --git a/backend/src/services/__tests__/test_llm_plugin_persistence.py b/backend/src/services/__tests__/test_llm_plugin_persistence.py index 3be0ac3b..1050a312 100644 --- a/backend/src/services/__tests__/test_llm_plugin_persistence.py +++ b/backend/src/services/__tests__/test_llm_plugin_persistence.py @@ -117,6 +117,12 @@ async def test_dashboard_validation_plugin_persists_task_and_environment_ids( # @PURPOSE: Deterministic LLM client double returning canonical analysis payload for persistence-path assertions. # @INVARIANT: analyze_dashboard is side-effect free and returns schema-compatible PASS result. class _FakeLLMClient: + """Fake LLM client for persistence tests. + + Always returns PASS status. FAIL and UNKNOWN persistence branches are NOT + covered by this fake — see coverage-planner findings. + """ + def __init__(self, **_kwargs): return None diff --git a/frontend/src/lib/components/dataset-review/ClarificationDialog.svelte b/frontend/src/lib/components/dataset-review/ClarificationDialog.svelte index d83978cc..c4fb3d09 100644 --- a/frontend/src/lib/components/dataset-review/ClarificationDialog.svelte +++ b/frontend/src/lib/components/dataset-review/ClarificationDialog.svelte @@ -51,6 +51,13 @@ }` : "0 / 0", ); + const fatigueHint = $derived( + clarificationSession?.remaining_count > 3 + ? "Очередь длинная: отвечайте по одному вопросу, пропускайте сомнительные и возвращайтесь позже." + : clarificationSession?.remaining_count > 0 + ? "Осталось немного: после ответа сразу появится следующий приоритетный вопрос." + : "Очередь уточнений закрыта. При необходимости можно возобновить сессию уточнений.", + ); $effect(() => { const questionId = currentQuestion?.question_id || ""; @@ -255,6 +262,10 @@ {/if} +
+ Следующий шаг: выбрать вариант, дать собственный ответ или пометить вопрос для expert review. +