{ "schema_version": "agent_detector_registry_v1", "updated_at": "2026-05-24", "purpose": "Machine-readable registry for detector names referenced by issue_catalog and business answer contracts. This keeps manual semantic findings on the path to repeatable replay/eval checks.", "detectors": { "missing_effective_runtime_json": { "kind": "artifact_presence", "automation_level": "automatic", "description": "Run artifact directory must contain effective_runtime.json before a replay can be accepted or saved as evidence.", "issue_codes": ["runtime_manifest_missing"], "inputs": ["artifacts/domain_runs//effective_runtime.json"], "check": { "required_files": ["effective_runtime.json"] } }, "default_prompt_version_missing_files": { "kind": "prompt_registry_healthcheck", "automation_level": "automatic", "description": "DEFAULT_PROMPT_VERSION points to prompt files that are missing from the prompt registry.", "issue_codes": ["prompt_registry_opaque"], "inputs": ["llm_normalizer/backend/src/services/promptBuilder.ts", "llm_normalizer/data/presets/*.json"], "check": { "command": "python scripts/prompt_registry_healthcheck.py" } }, "silent_prompt_fallback": { "kind": "prompt_registry_healthcheck", "automation_level": "automatic", "description": "Runtime used a fallback prompt without explicit source/hash metadata in artifacts.", "issue_codes": ["prompt_registry_opaque"], "inputs": ["effective_runtime.json", "prompt registry"], "check": { "manifest_fields": ["prompt_source", "prompt_hash"], "forbidden_prompt_sources": ["fallback", "unknown"] } }, "preset_version_mismatch": { "kind": "prompt_registry_healthcheck", "automation_level": "automatic", "description": "Active preset prompt version does not match the runtime prompt version used by the replay.", "issue_codes": ["prompt_registry_opaque"], "inputs": ["shared_llm_connection.json", "effective_runtime.json", "prompt presets"], "check": { "compare_fields": ["prompt_version"] } }, "forbidden_margin_terms": { "kind": "answer_text_regex_forbidden", "automation_level": "automatic", "description": "Margin answer contains wrong-domain terms such as fixed assets, amortization, bank, payment, or settlement vocabulary.", "issue_codes": ["margin_domain_leak_accounting_route"], "inputs": ["steps//output.md", "steps//turn.json"], "check": { "forbidden_patterns": [ "(?i)(амортизац|объект\\s+ОС|основн(ые|ых)?\\s+средств|payment_document|settlement|банк|оплат[аы])" ] } }, "missing_revenue_cogs_margin_fields": { "kind": "answer_text_required_any", "automation_level": "semi_automatic", "description": "Margin answer does not mention revenue, COGS/cost, gross profit, margin, or an honest limitation around those fields.", "issue_codes": ["margin_domain_leak_accounting_route"], "inputs": ["steps//output.md"], "check": { "required_patterns_any": [ "(?i)(выруч|себестоим|валов|марж|не хватает|не могу подтвердить|не подтвержден|unknown)" ] } }, "wrong_capability_family": { "kind": "trace_value_guard", "automation_level": "semi_automatic", "description": "Trace/capability family for a margin question points to another accounting family instead of margin/profitability/inventory evidence.", "issue_codes": ["margin_domain_leak_accounting_route"], "inputs": ["steps//turn.json"], "check": { "forbidden_trace_markers": ["fixed_asset", "amortization", "payment_document", "settlement"] } }, "margin_domain_leak_accounting_route": { "kind": "composite_detector", "automation_level": "semi_automatic", "description": "Composite margin-domain detector used by margin_profitability_v1 contract to group wrong-domain route leaks.", "issue_codes": ["margin_domain_leak_accounting_route"], "inputs": ["steps//output.md", "steps//turn.json"], "check": { "uses_detectors": ["forbidden_margin_terms", "wrong_capability_family"] } }, "margin_required_fields_missing": { "kind": "contract_field_detector", "automation_level": "semi_automatic", "description": "Margin answer misses required revenue/COGS/gross profit/margin fields or honest unknowns.", "issue_codes": ["margin_domain_leak_accounting_route"], "inputs": ["steps//output.md", "docs/orchestration/contracts/margin_profitability_v1.json"], "check": { "uses_detectors": ["missing_revenue_cogs_margin_fields"] } }, "margin_next_action_missing": { "kind": "limited_answer_next_action", "automation_level": "semi_automatic", "description": "Limited margin answer does not propose the next verifiable action.", "issue_codes": ["business_next_step_missing", "margin_domain_leak_accounting_route"], "inputs": ["steps//output.md"], "check": { "uses_detectors": ["limited_answer_without_next_action"] } }, "margin_payment_document_false_source": { "kind": "answer_text_regex_forbidden", "automation_level": "automatic", "description": "Margin answer treats payment/bank documents as the source for margin calculation.", "issue_codes": ["margin_domain_leak_accounting_route"], "inputs": ["steps//output.md"], "check": { "forbidden_patterns": ["(?i)(payment_document|банковск|плат[её]ж|оплат[аы]).{0,80}(марж|себестоим|валов)"] } }, "margin_os_amortization_leak": { "kind": "answer_text_regex_forbidden", "automation_level": "automatic", "description": "Margin answer leaks fixed-assets or amortization language.", "issue_codes": ["margin_domain_leak_accounting_route"], "inputs": ["steps//output.md"], "check": { "forbidden_patterns": ["(?i)(амортизац|объект\\s+ОС|основн(ые|ых)?\\s+средств)"] } }, "first_line_not_direct_answer": { "kind": "answer_text_shape", "automation_level": "semi_automatic", "description": "The first meaningful line is not a direct business answer for a direct user question.", "issue_codes": ["business_direct_answer_missing"], "inputs": ["steps//output.md"], "check": { "first_line_should_be": "business_answer_or_honest_boundary" } }, "top_level_scaffold_before_answer": { "kind": "answer_text_regex_forbidden_in_prefix", "automation_level": "automatic", "description": "Answer starts with scaffold/service narration before the user-facing business conclusion.", "issue_codes": ["business_direct_answer_missing"], "inputs": ["steps//output.md"], "check": { "prefix_line_count": 3, "forbidden_patterns": ["(?i)(для ответа|сначала|я проверю|я посмотрю|route|debug|capability)"] } }, "runtime_tokens_in_user_answer": { "kind": "answer_text_regex_forbidden", "automation_level": "automatic", "description": "Final user-facing answer contains runtime/debug/service tokens.", "issue_codes": ["technical_garbage_in_answer"], "inputs": ["steps//output.md"], "check": { "forbidden_patterns": ["(?i)(route_id|capability_id|runtime_|snapshot_items|debug|answer_object|selected_object)"] } }, "capability_ids_in_user_answer": { "kind": "answer_text_regex_forbidden", "automation_level": "automatic", "description": "Final user-facing answer contains capability ids or route ids.", "issue_codes": ["technical_garbage_in_answer"], "inputs": ["steps//output.md"], "check": { "forbidden_patterns": ["(?i)(capability[_ -]?id|route[_ -]?id|address\\.[a-z0-9_\\.]+)"] } }, "required_contract_fields_missing": { "kind": "contract_field_detector", "automation_level": "semi_automatic", "description": "Answer does not satisfy required fields from the expected business answer contract.", "issue_codes": ["accounting_contract_missing"], "inputs": ["steps//output.md", "docs/orchestration/contracts/.json"], "check": { "contract_field": "answer_surface.required_fields" } }, "limited_answer_without_next_action": { "kind": "answer_text_required_when_limited", "automation_level": "semi_automatic", "description": "Answer states a limitation but gives no concrete next action for recovering or narrowing the answer.", "issue_codes": ["business_next_step_missing"], "inputs": ["steps//output.md"], "check": { "limited_patterns": ["(?i)(не могу|не хватает|не подтвержден|нет данных|недостаточно)"], "required_next_action_patterns_any": ["(?i)(можно|следующ|уточн|перезапусти|проверь|выбери|нужен|добавь)"] } }, "route_candidate_needs_enablement": { "kind": "stage_review_signal", "automation_level": "semi_automatic", "description": "Stage review produced a route candidate that still needs runtime capability enablement.", "issue_codes": ["route_candidate_enablement_gap"], "inputs": ["run_review.json", "repair_targets.json"], "check": { "target_status": "needs_route_enablement" } } } }