NODEDC_1C/docs/orchestration/issue_catalog.json

518 lines
20 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{
"schema_version": "agent_issue_catalog_v1",
"updated_at": "2026-05-24",
"principles": [
"No accepted save without effective_runtime.json.",
"No auto-coder without allowed issue_code, root_layers, allowed/forbidden targets, rerun_matrix, and answer contract.",
"Subagents are read-only reviewers; Lead/Orchestrator owns final verdict and repair decision."
],
"issues": {
"runtime_manifest_missing": {
"severity": "P0",
"business_meaning": "Прогон нельзя воспроизвести, поэтому audit/repair/acceptance нельзя считать доказанными.",
"root_layers": ["run_reproducibility"],
"detectors": ["missing_effective_runtime_json"],
"allowed_patch_targets": [
"scripts/domain_case_loop.py",
"scripts/domain_truth_harness.py",
"scripts/stage_agent_loop.py",
"scripts/save_agent_semantic_run.py",
"scripts/agent_runtime_manifest.py"
],
"forbidden_patch_targets": [
"business routing",
"MCP runtime",
"domain contracts"
],
"rerun_matrix": [
"same_spec_direct_runner",
"same_spec_stage_runner",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"effective_runtime.json",
"git_sha",
"runner",
"llm_model",
"temperature",
"prompt_source",
"prompt_hash"
]
}
},
"prompt_registry_opaque": {
"severity": "P0",
"business_meaning": "Неясно, какой normalizer prompt реально исполняется.",
"root_layers": ["prompt_registry", "runtime_config"],
"detectors": [
"default_prompt_version_missing_files",
"silent_prompt_fallback",
"preset_version_mismatch"
],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/promptBuilder.ts",
"llm_normalizer/backend/src/config.ts",
"llm_normalizer/data/presets/*.json",
"scripts/prompt_registry_healthcheck.py",
"scripts/agent_runtime_manifest.py"
],
"forbidden_patch_targets": [
"domain routing rewrites",
"business answer heuristics"
],
"rerun_matrix": [
"prompt_healthcheck",
"normalizer_smoke",
"accepted_smoke_pack"
]
},
"margin_domain_leak_accounting_route": {
"severity": "P0",
"business_meaning": "Запрос про маржинальность номенклатуры ушёл в чужой бухгалтерский домен вместо выручки, себестоимости, валовой прибыли и процента маржи.",
"root_layers": ["intent", "route", "capability", "domain_contract"],
"expected_answer_contract": "margin_profitability_v1",
"detectors": [
"forbidden_margin_terms",
"missing_revenue_cogs_margin_fields",
"margin_payment_document_false_source",
"wrong_capability_family"
],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/addressQueryClassifier.ts",
"llm_normalizer/backend/src/services/addressInventoryIntentSignals.ts",
"llm_normalizer/backend/src/services/addressIntentResolver.ts",
"llm_normalizer/backend/src/services/addressCapabilityPolicy.ts",
"llm_normalizer/backend/src/services/addressFilterExtractor.ts",
"llm_normalizer/backend/src/services/address_runtime/**",
"docs/orchestration/contracts/margin_profitability_v1.json"
],
"forbidden_patch_targets": [
"fake data",
"silent heuristic masking",
"global orchestration rewrite",
"MCP protocol rewrite"
],
"rerun_matrix": [
"failed_margin_scenario",
"margin_neighbor_pack",
"wrong_domain_trap_pack",
"selected_object_followup_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"direct_answer_first",
"period",
"revenue_ex_vat_or_honest_unknown",
"cogs_or_honest_unknown",
"gross_profit_or_honest_unknown",
"margin_pct_or_honest_unknown",
"next_action_if_limited"
],
"must_not_have": [
"route ids",
"debug ids",
"fixed assets leak",
"amortization leak",
"payment document as margin source"
]
}
},
"business_direct_answer_missing": {
"severity": "P0",
"business_meaning": "Ответ не начинает с прямого бизнес-вывода, хотя пользователь задал прямой вопрос.",
"root_layers": ["answer_surface", "business_utility"],
"expected_answer_contract": "direct_answer_surface_v1",
"detectors": ["first_line_not_direct_answer", "top_level_scaffold_before_answer"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"llm_normalizer/backend/src/services/assistantService.ts"
],
"forbidden_patch_targets": [
"routing rewrites",
"fake evidence",
"global runtime rewrite"
],
"rerun_matrix": [
"failed_scenario",
"direct_answer_surface_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"direct_answer_first",
"business_meaning_before_service_context",
"honest_unknown_when_evidence_is_limited"
],
"must_not_have": [
"debug ids before answer",
"route ids before answer",
"service scaffold before answer"
]
}
},
"technical_garbage_in_answer": {
"severity": "P0",
"business_meaning": "Финальный ответ протащил debug/runtime/MCP-механику в пользовательскую поверхность.",
"root_layers": ["answer_surface", "business_utility"],
"expected_answer_contract": "technical_garbage_free_answer_v1",
"detectors": ["runtime_tokens_in_user_answer", "capability_ids_in_user_answer"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"llm_normalizer/backend/src/services/assistantService.ts"
],
"forbidden_patch_targets": [
"route masking",
"debug deletion from artifacts"
],
"rerun_matrix": [
"failed_scenario",
"technical_garbage_canary_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"business_answer_only",
"evidence_summary_when_useful"
],
"must_not_have": [
"route ids",
"capability ids",
"debug payload",
"raw runtime enums"
]
}
},
"accounting_contract_missing": {
"severity": "P1",
"business_meaning": "Ответ не раскрыл обязательный бухгалтерский/доказательный контракт для запрошенного расчёта.",
"root_layers": ["domain_contract", "answer_surface", "evidence"],
"detectors": ["required_contract_fields_missing"],
"allowed_patch_targets": [
"docs/orchestration/contracts/*.json",
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts"
],
"forbidden_patch_targets": [
"fake data",
"silent heuristic masking"
],
"rerun_matrix": [
"failed_scenario",
"contract_field_pack",
"accepted_smoke_pack"
]
},
"business_next_step_missing": {
"severity": "P2",
"business_meaning": "Ограниченный ответ не предлагает полезный следующий шаг.",
"root_layers": ["answer_surface", "business_utility"],
"expected_answer_contract": "limited_answer_next_action_v1",
"detectors": ["limited_answer_without_next_action"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts"
],
"forbidden_patch_targets": [
"evidence fabrication",
"route masking"
],
"rerun_matrix": [
"failed_scenario",
"limited_answer_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"clear_limitation",
"next_action_if_limited",
"no_overclaiming"
],
"must_not_have": [
"fake evidence",
"masked route failure"
]
}
},
"business_utility_gap": {
"severity": "P2",
"business_meaning": "Ответ технически заземлен, но для узкого бизнес follow-up остается слишком тяжелым или недостаточно практичным.",
"root_layers": ["answer_surface", "business_utility"],
"expected_answer_contract": "compact_business_followup_surface_v1",
"detectors": [
"business_answer_too_verbose_output",
"top_level_scaffold_before_answer",
"runtime_tokens_in_user_answer",
"capability_ids_in_user_answer",
"limited_answer_without_next_action"
],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/address_runtime/inventoryReplyBuilders.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"llm_normalizer/backend/src/services/assistantService.ts"
],
"forbidden_patch_targets": [
"route masking",
"fake evidence",
"evidence deletion from artifacts"
],
"rerun_matrix": [
"failed_scenario",
"answer_surface_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"direct_answer_first",
"compact_business_surface",
"short_evidence_basis",
"honest_limitation_when_needed"
],
"must_not_have": [
"verbose proof packet by default",
"technical ids",
"duplicated answer blocks"
]
}
},
"route_candidate_enablement_gap": {
"severity": "P1",
"business_meaning": "Планировщик понял бизнес-запрос, но route candidate ещё не исполняется как точная возможность.",
"root_layers": ["route_candidate", "runtime_capability"],
"detectors": ["route_candidate_needs_enablement"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/assistantMcpDiscoveryRuntimeBridge.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryPlanner.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryPilotExecutor.ts",
"llm_normalizer/backend/src/services/addressRecipeCatalog.ts"
],
"forbidden_patch_targets": [
"global orchestration rewrite",
"fake fixtures"
],
"rerun_matrix": [
"failed_scenario",
"route_candidate_pack",
"accepted_smoke_pack"
]
},
"backend_error_response": {
"severity": "P0",
"business_meaning": "Пользовательский ответ сорвался во внутреннюю runtime/LLM ошибку вместо полезного бизнес-ответа или честной границы.",
"root_layers": ["runtime_error", "business_utility"],
"detectors": ["backend_error_response_signal"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/assistantLivingChatRuntimeAdapter.ts",
"llm_normalizer/backend/src/services/assistantLivingChatHandlerRuntimeAdapter.ts",
"llm_normalizer/backend/src/services/assistantService.ts",
"scripts/review_assistant_stage1_run.py"
],
"forbidden_patch_targets": [
"fake success fallback",
"business routing rewrites",
"MCP protocol rewrite"
],
"rerun_matrix": [
"failed_gui_turn",
"same_saved_session_replay",
"big_gui_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"no backend_error reply_type",
"user-facing answer or honest boundary",
"trace remains diagnosable"
],
"must_not_have": [
"internal error text",
"empty assistant answer",
"masked fake business fact"
]
}
},
"year_ranking_direct_answer_missing": {
"severity": "P0",
"business_meaning": "Вопрос про самый доходный/лучший год не получает прямой годовой ranking-ответ в первой строке.",
"root_layers": ["answer_shape_mismatch", "business_utility", "ranking_answer_surface"],
"detectors": ["top_year_direct_answer_missing"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryRuntimeBridge.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts",
"scripts/review_assistant_stage1_run.py"
],
"forbidden_patch_targets": [
"fake revenue totals",
"global business overview rewrite",
"silent route masking"
],
"rerun_matrix": [
"failed_top_year_turn",
"business_overview_counterparty_pack",
"big_gui_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"direct winning year in first answer line",
"basis of ranking",
"amount or honest limitation",
"profit-vs-cashflow limitation if needed"
],
"must_not_have": [
"generic business overview first",
"route ids",
"unqualified чистая прибыль claim"
]
}
},
"purchase_date_vat_anchor_ambiguous": {
"severity": "P1",
"business_meaning": "Ответ по НДС на дату покупки считает налоговый период, но не объясняет, как дата покупки стала якорем периода.",
"root_layers": ["domain_anchor_gap", "field_mapping_gap", "answer_surface"],
"detectors": ["vat_purchase_date_anchor_missing"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/addressFilterExtractor.ts",
"llm_normalizer/backend/src/services/assistantTransitionPolicy.ts",
"scripts/review_assistant_stage1_run.py"
],
"forbidden_patch_targets": [
"fake purchase date",
"VAT route rewrite without evidence",
"MCP protocol rewrite"
],
"rerun_matrix": [
"failed_vat_purchase_date_turn",
"vat_tax_period_pack",
"selected_object_followup_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"purchase date anchor explanation",
"tax period window",
"sales/purchase book basis",
"honest unknown if exact purchase date is inferred"
],
"must_not_have": [
"unexplained period jump",
"fake document source",
"forecast presented as confirmed declaration"
]
}
},
"counterparty_value_flow_misrouted_to_company_profit": {
"severity": "P0",
"business_meaning": "Контрагентский вопрос про получили/заплатили/нетто отвечен company-level прибылью или 90/91/99 вместо контрагентского денежного потока.",
"root_layers": ["followup_action_resolution_gap", "answer_shape_mismatch", "domain_scope_leak"],
"detectors": [
"counterparty_value_flow_required_surface",
"counterparty_value_flow_profit_accounts_forbidden",
"counterparty_value_flow_profit_mismatch"
],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryRuntimeBridge.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryTurnInputAdapter.ts",
"llm_normalizer/backend/src/services/assistantTransitionPolicy.ts",
"scripts/review_assistant_stage1_run.py"
],
"forbidden_patch_targets": [
"fake counterparty totals",
"company profit fallback",
"global orchestration rewrite"
],
"rerun_matrix": [
"failed_counterparty_value_flow_turn",
"business_overview_counterparty_pack",
"cross_scope_followup_pack",
"accepted_smoke_pack"
],
"acceptance": {
"must_have": [
"counterparty scope",
"received amount or honest unknown",
"paid amount or honest unknown",
"net amount or honest unknown",
"company-profit boundary"
],
"must_not_have": [
"90/91/99 as direct counterparty answer",
"company profit as counterparty net",
"wrong selected entity"
]
}
},
"answer_layering_noise": {
"severity": "P1",
"business_meaning": "Ответ открывается лишним слоем рассуждений/рамок вместо короткого прямого вывода.",
"root_layers": ["answer_surface", "business_utility"],
"detectors": ["answer_layering_noise_signal"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"scripts/review_assistant_stage1_run.py"
],
"forbidden_patch_targets": [
"fake evidence",
"route masking"
],
"rerun_matrix": [
"failed_gui_turn",
"direct_answer_surface_pack",
"accepted_smoke_pack"
]
},
"business_answer_too_verbose": {
"severity": "P1",
"business_meaning": "Ответ слишком длинный для прямого бизнес-вопроса и снижает практическую полезность.",
"root_layers": ["answer_surface", "business_utility"],
"detectors": ["business_answer_too_verbose_output", "business_answer_too_verbose_signal"],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"scripts/review_assistant_stage1_run.py"
],
"forbidden_patch_targets": [
"evidence deletion from artifacts",
"business fact removal"
],
"rerun_matrix": [
"failed_gui_turn",
"direct_answer_surface_pack",
"accepted_smoke_pack"
]
},
"bank_counterparty_misclassified_as_business_partner": {
"severity": "P1",
"business_meaning": "Банк/финансовая организация ошибочно подана как обычный клиент/поставщик без роли, назначения платежа и договорного контекста.",
"root_layers": ["business_semantic_role_gap", "domain_scope"],
"detectors": [
"bank_counterparty_boundary_required",
"bank_counterparty_role_boundary_missing"
],
"allowed_patch_targets": [
"llm_normalizer/backend/src/services/address_runtime/composeStage.ts",
"llm_normalizer/backend/src/services/assistantMcpDiscoveryResponseCandidate.ts",
"scripts/review_assistant_stage1_run.py"
],
"forbidden_patch_targets": [
"hard-coded bank blacklist as final truth",
"fake operation purpose",
"global routing rewrite"
],
"rerun_matrix": [
"failed_bank_counterparty_turn",
"counterparty_value_pack",
"accepted_smoke_pack"
]
}
}
}