From 87a0b77dae7cbb2953c0fd0b788ac624f6cb2f9e Mon Sep 17 00:00:00 2001 From: "cristiano.hoshikawa" Date: Mon, 31 Aug 2026 14:13:51 -0300 Subject: [PATCH] Ajustes no agente de contas --- app/__pycache__/__init__.cpython-313.pyc | Bin 150 -> 150 bytes app/__pycache__/main.cpython-313.pyc | Bin 37578 -> 37578 bytes app/__pycache__/state.cpython-313.pyc | Bin 3176 -> 3396 bytes .../contas_prompting.cpython-313.pyc | Bin 1060 -> 1060 bytes .../contestacao_agent.cpython-313.pyc | Bin 5301 -> 5301 bytes .../__pycache__/faturas_agent.cpython-313.pyc | Bin 6536 -> 6536 bytes .../__pycache__/prompting.cpython-313.pyc | Bin 1147 -> 1147 bytes .../__pycache__/runtime.cpython-313.pyc | Bin 434 -> 434 bytes .../suporte_contas_agent.cpython-313.pyc | Bin 5897 -> 5897 bytes .../__pycache__/vas_agent.cpython-313.pyc | Bin 5712 -> 5712 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 232 -> 232 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 328 -> 328 bytes .../contas/__pycache__/client.cpython-313.pyc | Bin 51885 -> 51885 bytes .../contestation_rules.cpython-313.pyc | Bin 13576 -> 13576 bytes .../contestation_validation.cpython-313.pyc | Bin 25401 -> 25401 bytes .../conversation_policy.cpython-313.pyc | Bin 0 -> 16689 bytes .../__pycache__/ic_tags.cpython-313.pyc | Bin 17226 -> 17226 bytes .../informational_context.cpython-313.pyc | Bin 3495 -> 3495 bytes .../invoice_context.cpython-313.pyc | Bin 20357 -> 20357 bytes .../invoice_models.cpython-313.pyc | Bin 1803 -> 1803 bytes .../invoice_resolver.cpython-313.pyc | Bin 56048 -> 56048 bytes .../__pycache__/item_matcher.cpython-313.pyc | Bin 9916 -> 9916 bytes .../line_reference.cpython-313.pyc | Bin 3429 -> 3429 bytes .../pro_rata_rules.cpython-313.pyc | Bin 17673 -> 17673 bytes .../protocol_triplets.cpython-313.pyc | Bin 7736 -> 7736 bytes .../__pycache__/rct_policy.cpython-313.pyc | Bin 6329 -> 6329 bytes .../__pycache__/service.cpython-313.pyc | Bin 21632 -> 21632 bytes .../string_metrics.cpython-313.pyc | Bin 6302 -> 6302 bytes .../vas_cancellation_message.cpython-313.pyc | Bin 16323 -> 16323 bytes .../__pycache__/vas_variation.cpython-313.pyc | Bin 42128 -> 42128 bytes .../workflow_actions.cpython-313.pyc | Bin 143137 -> 143137 bytes app/domain/contas/conversation_policy.py | 277 ++++++++++++++++++ .../secure_pdf_crypto.cpython-313.pyc | Bin 2474 -> 2474 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 935 -> 935 bytes .../__pycache__/bill_parser.cpython-313.pyc | Bin 23739 -> 23739 bytes .../bill_processor.cpython-313.pyc | Bin 36254 -> 36254 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 302 -> 302 bytes .../tim_guardrails.cpython-313.pyc | Bin 18166 -> 18166 bytes .../__pycache__/tim_judges.cpython-313.pyc | Bin 5486 -> 5486 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 173 -> 173 bytes .../__pycache__/aluc.cpython-313.pyc | Bin 6388 -> 6388 bytes .../ausencia_oferta_proativa.cpython-313.pyc | Bin 9810 -> 9810 bytes .../__pycache__/fraseologia.cpython-313.pyc | Bin 7527 -> 7527 bytes .../__pycache__/out_of_scope.cpython-313.pyc | Bin 17019 -> 17019 bytes .../__pycache__/revprec.cpython-313.pyc | Bin 5612 -> 5612 bytes .../__pycache__/rqlt.cpython-313.pyc | Bin 1095 -> 1095 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 164 -> 164 bytes .../telemetry_observer.cpython-313.pyc | Bin 4987 -> 4987 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 256 -> 256 bytes .../tool_renderers.cpython-313.pyc | Bin 5429 -> 5429 bytes app/state.py | 6 + .../__pycache__/agent_graph.cpython-313.pyc | Bin 68864 -> 71690 bytes app/workflows/agent_graph.py | 34 ++- config/routing.yaml | 11 + config/tools.yaml | 7 +- .../__pycache__/__init__.cpython-313.pyc | Bin 157 -> 157 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 165 -> 165 bytes .../__pycache__/__init__.cpython-313.pyc | Bin 183 -> 183 bytes .../authorized_lines_service.cpython-313.pyc | Bin 4935 -> 4935 bytes .../discount_history_service.cpython-313.pyc | Bin 4879 -> 4879 bytes .../__pycache__/line_policy.cpython-313.pyc | Bin 3072 -> 3072 bytes .../line_policy_alt1.cpython-313.pyc | Bin 3066 -> 3086 bytes .../line_policy_alt2.cpython-313.pyc | Bin 5805 -> 5825 bytes .../__pycache__/main.cpython-313.pyc | Bin 86553 -> 93080 bytes contas_mcp/servers/contas_mcp_server/main.py | 123 +++++++- .../FIX_CONTAS_REPORT_20260831_SECOND_PASS.md | 27 ++ ...S_RESIDUAL_CONVERSATION_PARITY_20260831.md | 63 ++++ .../conftest.cpython-313-pytest-9.0.2.pyc | Bin 825 -> 853 bytes ...sarial_parity.cpython-313-pytest-9.0.2.pyc | Bin 53224 -> 53252 bytes ...ntract_parity.cpython-313-pytest-9.0.2.pyc | Bin 37540 -> 37568 bytes ...nd_guardrails.cpython-313-pytest-9.0.2.pyc | Bin 4255 -> 4283 bytes ...rapper_parity.cpython-313-pytest-9.0.2.pyc | Bin 29067 -> 29095 bytes ...site_workflow.cpython-313-pytest-9.0.2.pyc | Bin 60198 -> 60226 bytes ...aining_parity.cpython-313-pytest-9.0.2.pyc | Bin 40359 -> 40387 bytes ...icy_residuals.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 30003 bytes ...s_domain_mock.cpython-313-pytest-9.0.2.pyc | Bin 64303 -> 64331 bytes ...ation_routing.cpython-313-pytest-9.0.2.pyc | Bin 17209 -> 17237 bytes ...ss_rules_full.cpython-313-pytest-9.0.2.pyc | Bin 23183 -> 23211 bytes ...ilure_mapping.cpython-313-pytest-9.0.2.pyc | Bin 7660 -> 7688 bytes ..._out_of_scope.cpython-313-pytest-9.0.2.pyc | Bin 3503 -> 3531 bytes ...ck_regression.cpython-313-pytest-9.0.2.pyc | Bin 8373 -> 8401 bytes ...ty_resolution.cpython-313-pytest-9.0.2.pyc | Bin 10084 -> 10112 bytes ...y_mcp_service.cpython-313-pytest-9.0.2.pyc | Bin 20536 -> 20564 bytes ...aining_parity.cpython-313-pytest-9.0.2.pyc | Bin 17938 -> 17966 bytes ...ls_judges_spi.cpython-313-pytest-9.0.2.pyc | Bin 10121 -> 10149 bytes ...rity_extended.cpython-313-pytest-9.0.2.pyc | Bin 39464 -> 39492 bytes ...ent_gap_fixes.cpython-313-pytest-9.0.2.pyc | Bin 6812 -> 6840 bytes ...ion_directive.cpython-313-pytest-9.0.2.pyc | Bin 5870 -> 5898 bytes ...ive_structure.cpython-313-pytest-9.0.2.pyc | Bin 18958 -> 18986 bytes ...rag_directive.cpython-313-pytest-9.0.2.pyc | Bin 9446 -> 9474 bytes ...k_zero_legacy.cpython-313-pytest-9.0.2.pyc | Bin 1781 -> 1809 bytes ...binary_parity.cpython-313-pytest-9.0.2.pyc | Bin 12215 -> 12243 bytes ..._dict_history.cpython-313-pytest-9.0.2.pyc | Bin 1973 -> 2001 bytes ...faults_parity.cpython-313-pytest-9.0.2.pyc | Bin 6437 -> 6465 bytes ...drail_context.cpython-313-pytest-9.0.2.pyc | Bin 8341 -> 8369 bytes ...user_feedback.cpython-313-pytest-9.0.2.pyc | Bin 7679 -> 7707 bytes ...mework_native.cpython-313-pytest-9.0.2.pyc | Bin 43108 -> 43136 bytes ...inal_response.cpython-313-pytest-9.0.2.pyc | Bin 4544 -> 4572 bytes ...andoff_policy.cpython-313-pytest-9.0.2.pyc | Bin 10763 -> 10791 bytes ...ed_meaningful.cpython-313-pytest-9.0.2.pyc | Bin 4617 -> 4645 bytes ..._alternatives.cpython-313-pytest-9.0.2.pyc | Bin 23140 -> 23168 bytes ...subject_guard.cpython-313-pytest-9.0.2.pyc | Bin 21822 -> 21850 bytes ...ct_resolution.cpython-313-pytest-9.0.2.pyc | Bin 0 -> 5074 bytes ...cy_dependency.cpython-313-pytest-9.0.2.pyc | Bin 1891 -> 1919 bytes ..._code_mapping.cpython-313-pytest-9.0.2.pyc | Bin 23694 -> 23722 bytes ...compatibility.cpython-313-pytest-9.0.2.pyc | Bin 20445 -> 20473 bytes ...ider_boundary.cpython-313-pytest-9.0.2.pyc | Bin 5710 -> 5738 bytes ...istry_actions.cpython-313-pytest-9.0.2.pyc | Bin 16940 -> 16968 bytes ...liance_anatel.cpython-313-pytest-9.0.2.pyc | Bin 17436 -> 17464 bytes ...on_validation.cpython-313-pytest-9.0.2.pyc | Bin 51104 -> 51132 bytes ...transcription.cpython-313-pytest-9.0.2.pyc | Bin 11600 -> 11628 bytes ...ation_message.cpython-313-pytest-9.0.2.pyc | Bin 23881 -> 23909 bytes ...vas_variation.cpython-313-pytest-9.0.2.pyc | Bin 142645 -> 142673 bytes ...n_adversarial.cpython-313-pytest-9.0.2.pyc | Bin 43297 -> 43325 bytes ...orkflow_cases.cpython-313-pytest-9.0.2.pyc | Bin 18723 -> 18751 bytes ...act_hardcodes.cpython-313-pytest-9.0.2.pyc | Bin 9967 -> 9995 bytes ...a_full_parity.cpython-313-pytest-9.0.2.pyc | Bin 18856 -> 18884 bytes ...ional_context.cpython-313-pytest-9.0.2.pyc | Bin 5896 -> 5924 bytes ...ration_compat.cpython-313-pytest-9.0.2.pyc | Bin 14138 -> 14166 bytes ...and_contracts.cpython-313-pytest-9.0.2.pyc | Bin 14539 -> 14567 bytes ...ty_pente_fino.cpython-313-pytest-9.0.2.pyc | Bin 41079 -> 30813 bytes ...c_uncertainty.cpython-313-pytest-9.0.2.pyc | Bin 8243 -> 8271 bytes ...n_all_domains.cpython-313-pytest-9.0.2.pyc | Bin 26374 -> 31336 bytes ...nto_grounding.cpython-313-pytest-9.0.2.pyc | Bin 4951 -> 4979 bytes ..._continuation.cpython-313-pytest-9.0.2.pyc | Bin 18754 -> 18782 bytes ...ntract_parity.cpython-313-pytest-9.0.2.pyc | Bin 12416 -> 12444 bytes ...d_idempotency.cpython-313-pytest-9.0.2.pyc | Bin 14781 -> 14809 bytes ...tadata_parity.cpython-313-pytest-9.0.2.pyc | Bin 34883 -> 34911 bytes ...andoff_bypass.cpython-313-pytest-9.0.2.pyc | Bin 14376 -> 14404 bytes ...eration_types.cpython-313-pytest-9.0.2.pyc | Bin 6136 -> 6164 bytes ...ispute_parity.cpython-313-pytest-9.0.2.pyc | Bin 13779 -> 13807 bytes ...onse_renderer.cpython-313-pytest-9.0.2.pyc | Bin 4403 -> 4431 bytes ...ecution_latch.cpython-313-pytest-9.0.2.pyc | Bin 7681 -> 7709 bytes ...ast_contracts.cpython-313-pytest-9.0.2.pyc | Bin 17442 -> 17470 bytes ...st_contas_conversation_policy_residuals.py | 107 +++++++ .../test_multiple_vas_subject_resolution.py | 25 ++ ...t_subject_entity_resolution_all_domains.py | 43 +++ 137 files changed, 715 insertions(+), 8 deletions(-) create mode 100644 app/domain/contas/__pycache__/conversation_policy.cpython-313.pyc create mode 100644 app/domain/contas/conversation_policy.py create mode 100644 docs/FIX_CONTAS_REPORT_20260831_SECOND_PASS.md create mode 100644 docs/FIX_CONTAS_RESIDUAL_CONVERSATION_PARITY_20260831.md create mode 100644 tests/migration/__pycache__/test_contas_conversation_policy_residuals.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/__pycache__/test_multiple_vas_subject_resolution.cpython-313-pytest-9.0.2.pyc create mode 100644 tests/migration/test_contas_conversation_policy_residuals.py create mode 100644 tests/migration/test_multiple_vas_subject_resolution.py diff --git a/app/__pycache__/__init__.cpython-313.pyc b/app/__pycache__/__init__.cpython-313.pyc index 562654f476428ef14ca0374c3855b076ac0bb243..5318255507b8326d2a476c25aa50387b20589925 100644 GIT binary patch delta 19 ZcmbQnIE|6}GcPX}0}${nn>vxZ8vrdS1i=6R delta 19 ZcmbQnIE|6}GcPX}0}!mdIB6nxHvln~1%v*HC8fo;WPvhesYS(!AT9B5 z+1%9P;>7gSl?;BGJhwRFWGd7T6U<0=bMpTr2@3J}@&fGTvuU{KDqQ$f!O+a)Ih+ J1`rFZ695HVaYg_D delta 134 zcmX>i^+JO8GcPX}0}!mdI4MhDB5w)fnvG2>nK^>(in!D5H61orvP@x_T+G?R=rZ{S zr#EBlW*4qlCe~{#%0&T_ukh$Px&ZYS1%QY^AaRSsCO1E&G$+-rCbAn}2j Zk&*E}gW?x98%C80k_%KnGXNQ2eE?|aBmMvY diff --git a/app/agents/__pycache__/contas_prompting.cpython-313.pyc b/app/agents/__pycache__/contas_prompting.cpython-313.pyc index 636a78116d348fa246497043a71ab9dda148adf4..f9af64fe7a593f21b5e655c50554fed4608ef994 100644 GIT binary patch delta 20 acmZ3&v4n&BGcPX}0}${no4S!(k_7-XngpEy delta 20 acmZ3&v4n&BGcPX}0}!mdIB6rdBntpJ$^~Em diff --git a/app/agents/__pycache__/contestacao_agent.cpython-313.pyc b/app/agents/__pycache__/contestacao_agent.cpython-313.pyc index 2e9413673dff74b3a5423c0f2943ed4e02d6c163..ab4790f885044c42f9d18240beacf728e90ca92d 100644 GIT binary patch delta 20 acmdn0xmA<`7cTLm-# delta 20 acmeA$?l9*5%*)Hg00b*9PTI&_D+vHRiv{-p diff --git a/app/agents/__pycache__/prompting.cpython-313.pyc b/app/agents/__pycache__/prompting.cpython-313.pyc index d5f57c0d3d84f1eb96a8c163637fdadc9065bc97..86f649859ff05f17e04e0105661949aed007645e 100644 GIT binary patch delta 20 acmey(@tcGDGcPX}0}${no4S#^fCT_TG6kXl delta 20 acmey(@tcGDGcPX}0}!mdIB6qy0Sf>}Vg_XZ diff --git a/app/agents/__pycache__/runtime.cpython-313.pyc b/app/agents/__pycache__/runtime.cpython-313.pyc index ba22c1b4c8a26eb01b950ae5c1630cf2ee7d8c50..7a6d2768d76be47a7ce12c20542e2aafbb6c2e9d 100644 GIT binary patch delta 20 acmdnQyos6nGcPX}0}${no4S#EIU@i!69qZ| delta 20 acmdnQyos6nGcPX}0}!mdIB6sIaz+3=Lk0Z+ diff --git a/app/agents/__pycache__/suporte_contas_agent.cpython-313.pyc b/app/agents/__pycache__/suporte_contas_agent.cpython-313.pyc index 7bad76640b72446080c91ab5547be222e88ad1bc..c641fb9f42866654d31e174069bbe0b6a429cc9c 100644 GIT binary patch delta 20 acmeCw>(t}^%*)Hg00ex?rf%f^Ck6mF%mu0d delta 20 acmeCw>(t}^%*)Hg00b*9PTI)*PYeJ&{040R diff --git a/app/agents/__pycache__/vas_agent.cpython-313.pyc b/app/agents/__pycache__/vas_agent.cpython-313.pyc index 01344c2af37fd3e642b4d6c4f4c35ac80bcdeca4..cbe1f48d12b93bf98c477b8972b8e3e47ba23d97 100644 GIT binary patch delta 20 acmcbhb3upuGcPX}0}${no4S$PRSWvyEE&w?L1-AeI delta 19 ZcmaFC_=1u9GcPX}0}!mdIB6pHT>w3B26_Mh diff --git a/app/domain/contas/__pycache__/__init__.cpython-313.pyc b/app/domain/contas/__pycache__/__init__.cpython-313.pyc index e32cc5bc395dd1a4523ac521598fc250feca6ae8..d82e8666d3ca554ae0a52874d80efd191adbeaa7 100644 GIT binary patch delta 20 acmX@Xbb^WdGcPX}0}${no4S$PmJt9sUj+I9 delta 20 acmX@Xbb^WdGcPX}0}!mdIB6rdEh7Lvj|IH| diff --git a/app/domain/contas/__pycache__/client.cpython-313.pyc b/app/domain/contas/__pycache__/client.cpython-313.pyc index 66f82efa617cab2f2cc5d9ae66fb375ad78b563c..5c1a010662e74aeccffeeffab341aa132665c290 100644 GIT binary patch delta 22 ccmZ2Gm3i${X710tyj%=Gz_)DbM(#zY08i5g9smFU delta 22 dcmZ2Gm3i${X710tyj%=Gu=3)hjogb)0RUA42jKt! diff --git a/app/domain/contas/__pycache__/contestation_rules.cpython-313.pyc b/app/domain/contas/__pycache__/contestation_rules.cpython-313.pyc index d187f0fe66d7e72c2365f05b56bf146e3d0ca4fd..562cded2d87122ca8e351262098154e2f3f4f1a3 100644 GIT binary patch delta 20 acmeCk>d4~$%*)Hg00ex?rf%f^YXSg3G6p>W delta 20 acmeCk>d4~$%*)Hg00b*9PTI)**8~7XVg~>K diff --git a/app/domain/contas/__pycache__/contestation_validation.cpython-313.pyc b/app/domain/contas/__pycache__/contestation_validation.cpython-313.pyc index 7e25ba783a30561ce36659925c60a86cacd0d6ca..7adf0faab24ecd52afb5966a4d49f6241c953d09 100644 GIT binary patch delta 22 ccmdmajB)2NM()qNyj%=Gz_)DbMsB@i09Ty`xc~qF delta 22 ccmdmajB)2NM()qNyj%=Gu=3)hjof<409?%nd;kCd diff --git a/app/domain/contas/__pycache__/conversation_policy.cpython-313.pyc b/app/domain/contas/__pycache__/conversation_policy.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..671d2434aece4d8aa706cf12b149b1d698ebe9a9 GIT binary patch literal 16689 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 T{wLivtm*$8JgsB1e~A149tey1 literal 0 HcmV?d00001 diff --git a/app/domain/contas/__pycache__/ic_tags.cpython-313.pyc b/app/domain/contas/__pycache__/ic_tags.cpython-313.pyc index 1ef731d68c292a4745be330fe218e033b7cdb1a8..3e338ee3386642c178e69f3474cace483fa01719 100644 GIT binary patch delta 22 ccmX@r#(1iYk^3_*FBbz4@GYCVk=x!G08p3)OaK4? delta 22 ccmX@r#(1iYk^3_*FBbz4th_jBBe%UX09D8b4*&oF diff --git a/app/domain/contas/__pycache__/informational_context.cpython-313.pyc b/app/domain/contas/__pycache__/informational_context.cpython-313.pyc index 6d0e3e3faf1d383a131fdf3f7989e95c6ea1768a..dc5cf8f7011fa70dff9f12a5ab24b59b1fd0cd80 100644 GIT binary patch delta 20 acmZ23y*nMB%*)Hg00ex?rY_`W2LLSt1W^D0 delta 19 ZcmeC?>*nMB%*)Hg00b*9PFl##4gfK51rz`P diff --git a/app/domain/contas/__pycache__/invoice_resolver.cpython-313.pyc b/app/domain/contas/__pycache__/invoice_resolver.cpython-313.pyc index a6d6def060bdbada83f21791d5bfa9c0d0193b25..dc0ba9a48ecc08f96d65ff3623669078adeb3afd 100644 GIT binary patch delta 22 ccmeycmHER~X710tyj%=Gz_)DbM((G#0AK_NHvj+t delta 22 dcmeycmHER~X710tyj%=Gu=3)hjoeRf0RUw*2>Jj3 diff --git a/app/domain/contas/__pycache__/item_matcher.cpython-313.pyc b/app/domain/contas/__pycache__/item_matcher.cpython-313.pyc index 58d7bad39997ef60a9c4d249d7c8143ba11d5820..680109451e54ae6789a44c71bac5ef23e0208429 100644 GIT binary patch delta 20 acmdnvyT_ONGcPX}0}${no4S#EqZ$B1Fa{9- delta 20 acmdnvyT_ONGcPX}0}!mdIB6sIMl}FPU<{9 diff --git a/app/domain/contas/__pycache__/string_metrics.cpython-313.pyc b/app/domain/contas/__pycache__/string_metrics.cpython-313.pyc index a21b7080898cef575a47c74a8fdc1bb50bf3044f..d1f8b7d46f7617e76e2f05ed222b61c1896be2c6 100644 GIT binary patch delta 20 acmbPdIM0y#GcPX}0}${no4S#EvIGD+f(3B^ delta 20 acmbPdIM0y#GcPX}0}!mbIB6sIWC;L2xdt@= diff --git a/app/domain/contas/__pycache__/vas_cancellation_message.cpython-313.pyc b/app/domain/contas/__pycache__/vas_cancellation_message.cpython-313.pyc index 3d0b6a0c3602b6e2c3df628140ca5625f4612a2f..5be3a9e84f72a24ea1be557514ecff41cd9157df 100644 GIT binary patch delta 20 acmX?Hf4H9eGcPX}0}${no4S#EhdlsGX$GSJ delta 20 acmX?Hf4H9eGcPX}0}!mbIB6sI4toGlpa*9F diff --git a/app/domain/contas/__pycache__/vas_variation.cpython-313.pyc b/app/domain/contas/__pycache__/vas_variation.cpython-313.pyc index ada21a1f8281370d2ef12822c769857783fbd8f6..8193567fb8f66ebb522103dd51e7d1bdc83e2e5d 100644 GIT binary patch delta 22 ccmbPml4-(8ChpI?yj%=Gz_)DbM()-n08*6)2LJ#7 delta 22 ccmbPml4-(8ChpI?yj%=Gu Iterable[dict[str, Any]]: + if isinstance(value, dict): + yield value + for child in value.values(): + yield from _walk_dicts(child) + elif isinstance(value, list): + for child in value: + yield from _walk_dicts(child) + + +def _first_dict_value(state: dict[str, Any], keys: tuple[str, ...]) -> dict[str, Any] | None: + for obj in _walk_dicts(state): + for key in keys: + value = obj.get(key) + if isinstance(value, dict) and value: + return value + return None + + +def _explicit_answer(text: str) -> str | None: + raw = str(text or "").strip() + if _YES_RE.search(raw): + return "YES" + if _NO_RE.search(raw): + return "NO" + return None + + +def _previous_assistant_intent(state: dict[str, Any]) -> str: + for item in reversed(state.get("history") or []): + if not isinstance(item, dict) or str(item.get("role") or "") != "assistant": + continue + metadata = item.get("metadata") if isinstance(item.get("metadata"), dict) else {} + direct = str(metadata.get("intent") or "").strip() + if direct: + return direct + decision = metadata.get("route_decision") + if isinstance(decision, dict): + return str(decision.get("intent") or "").strip() + return "" + + +def _has_live_transaction(state: dict[str, Any]) -> bool: + status = str(state.get("transaction_status") or "").upper() + if status in {"COLLECTING_PARAMETERS", "AWAITING_CONFIRMATION", "WORKFLOW_PAUSED", "TOOL_RESULT_CLARIFICATION"}: + return True + return bool(state.get("active_transaction") or state.get("pending_tool_call") or state.get("pending_domain_workflow")) + + +def is_regulatory_threat(text: str) -> bool: + return bool(_REGULATORY_RE.search(str(text or ""))) + + +def _focused_subjects(state: dict[str, Any]) -> list[str]: + out: list[str] = [] + candidates = [ + state.get("active_transaction"), state.get("last_transaction"), + state.get("selected_tool_call"), state.get("pending_tool_call"), + (state.get("context") or {}).get("focused_items") if isinstance(state.get("context"), dict) else None, + ] + for candidate in candidates: + if isinstance(candidate, list): + for item in candidate: + if isinstance(item, str) and item.strip(): + out.append(item.strip()) + continue + if not isinstance(candidate, dict): + continue + args = candidate.get("arguments") if isinstance(candidate.get("arguments"), dict) else candidate + for key in ("subject", "item", "service", "name"): + value = args.get(key) if isinstance(args, dict) else None + if isinstance(value, str) and value.strip(): + out.append(value.strip()) + values = args.get("items") if isinstance(args, dict) else None + if isinstance(values, list): + for item in values: + if isinstance(item, dict): + value = item.get("name") or item.get("desc") or item.get("subject") + if value: + out.append(str(value).strip()) + return list(dict.fromkeys(x for x in out if x)) + + +def _retention_items(state: dict[str, Any]) -> list[dict[str, Any]]: + invoice_detail = _first_dict_value(state, ("invoice_detail", "invoiceDetail")) + if not invoice_detail: + return [] + invoice_variation = _first_dict_value(state, ("invoice_variation", "invoiceVariation", "billing_analysis")) + try: + items = varied_avulso_items( + invoice_variation=invoice_variation, + invoice_detail=invoice_detail, + resolver=InvoiceResolver(), + by_charge=True, + ) + except Exception: + return [] + if not items: + return [] + return [ + { + "name": item.canonical_name, + "msisdn": item.msisdn, + "value": str(item.value) if item.value is not None else None, + "charge_date": item.charge_date, + } + for item in items if item.msisdn and item.canonical_name + ] + + +def evaluate(state: dict[str, Any]) -> PolicyDecision | None: + """Contas-only conversational policy executed after generic routing. + + It never performs a side effect. It may only (a) answer/reprompt, (b) enrich + routing, or (c) prepare explicit domain context consumed by normal framework + transaction machinery. + """ + text = str(state.get("sanitized_input") or state.get("user_text") or "").strip() + route_decision = state.get("route_decision") if isinstance(state.get("route_decision"), dict) else {} + method = str(route_decision.get("method") or "") + intent = str(state.get("intent") or route_decision.get("intent") or "") + + # 1) Consecutive incomprehensible utterances. A router fallback is the generic, + # architecture-native signal that no intent was understood. Any understood turn + # resets the counter. Default requirement is three consecutive failures. + previous_count = int(state.get("no_match_count") or 0) + if intent == "contas_no_match": + count = previous_count + 1 + limit = max(1, int(os.getenv("CONTAS_NO_MATCH_MAX_CONSECUTIVE", "3"))) + if count >= limit: + return PolicyDecision( + route="end_session", intent="contas_no_match_terminal", + reason="no_match_limit_reached", + patch={"no_match_count": count, "terminal_status": "erro_no_match", + "conversation_terminal_message": "Não consegui compreender sua solicitação após três tentativas. Vou encerrar este atendimento para evitar uma ação incorreta."}, + ) + return PolicyDecision( + route="conversation_policy_response", intent="contas_no_match_retry", + answer="Desculpe, não entendi. Poderia repetir de outra forma?", + reason="no_match_retry", patch={"no_match_count": count}, + ) + + reset_patch: dict[str, Any] = {"no_match_count": 0} if previous_count else {} + + # Explicit conversational closure is a lifecycle signal, not a new business + # intent. Never consume it while a transaction/workflow is still live. + if _CLOSE_RE.search(text) and not _has_live_transaction(state): + return PolicyDecision( + route="end_session", intent="contas_conversation_close", + reason="explicit_customer_closure", + patch={**reset_patch, "terminal_status": "resolvido", + "conversation_terminal_message": "Atendimento encerrado. Obrigado pelo contato."}, + ) + + # A short plural continuation after an invoice explanation belongs to that + # explanation; it must not be mistaken for generic finalization merely because + # it contains an affirmative such as "pode seguir". The invoice agent keeps + # the prior evidence/context and can explain the two referenced charges. + previous_intent = _previous_assistant_intent(state) + if ( + previous_intent == "contas_invoice_explanation" + and _PLURAL_CONTINUE_RE.search(text) + and not _has_live_transaction(state) + ): + return PolicyDecision( + route="faturas_agent", intent="contas_invoice_explanation", + reason="invoice_plural_context_continuation", + patch={**reset_patch, "mcp_tools": ["invoice_explanation"], + "_route_metadata": {"contextual_reentry": True, "original_input": text}}, + ) + + # 2) Regulatory/legal wording is not itself an action. Only preserve action + # semantics when an entity is already concretely in focus in transaction state. + if is_regulatory_threat(text): + focused = _focused_subjects(state) + if focused: + subject = focused[0] + return PolicyDecision( + route="contestacao_agent", intent="contas_vas_cancel", + reason="regulatory_threat_with_focused_entity", + patch={**reset_patch, "regulatory_context": {"threat": True, "focused_items": focused}, + "mcp_tools": ["consultar_vas", "cancelar_vas_avulso"], + "context": {**(state.get("context") or {}), "focused_items": focused, "regulatory_threat": True}}, + ) + # Broad complaint: never invent an item/action from the invoice. + return PolicyDecision( + route="suporte_contas_agent", intent="contas_regulatory_complaint", + reason="regulatory_threat_without_focused_entity", + patch={**reset_patch, "regulatory_context": {"threat": True, "focused_items": []}, "mcp_tools": []}, + ) + + # 3) Two-step human-retention policy. It is only eligible when the router would + # hand off AND authoritative invoice evidence proves a varied cancellable VAS. + retention = state.get("contas_retention") if isinstance(state.get("contas_retention"), dict) else {} + pending = str(retention.get("pending_stage") or "") + offered = list(retention.get("stages_offered") or []) + retained_items = list(retention.get("items") or []) + + if pending: + answer_kind = _explicit_answer(text) + if pending == "explain": + if answer_kind == "YES": + return PolicyDecision( + route="faturas_agent", intent="contas_invoice_explanation", + reason="human_retention_explanation_accepted", + patch={**reset_patch, "mcp_tools": ["invoice_explanation"], + "contas_retention": {"pending_stage": None, "stages_offered": offered, "items": retained_items}}, + ) + if answer_kind == "NO" or _HUMAN_RE.search(text): + names = ", ".join(str(x.get("name")) for x in retained_items if isinstance(x, dict) and x.get("name")) + return PolicyDecision( + route="conversation_policy_response", intent="contas_retention_continue", + answer=(f"Antes de transferir, posso tratar o cancelamento dos serviços que participaram da variação da conta: {names}. Deseja que eu prossiga?" if names else "Antes de transferir, posso tratar os serviços que participaram da variação da conta. Deseja que eu prossiga?"), + reason="human_retention_offer_continue", + patch={**reset_patch, "contas_retention": {"pending_stage": "continue", "stages_offered": list(dict.fromkeys([*offered, "continue"])), "items": retained_items}}, + ) + elif pending == "continue": + if answer_kind == "YES": + names = [str(x.get("name")) for x in retained_items if isinstance(x, dict) and x.get("name")] + context = {**(state.get("context") or {}), "retention_items": retained_items, "focused_items": names} + # Route through the normal transactional agent. No side effect here. + semantic_request = "cancelar " + " e ".join(names) if names else text + return PolicyDecision( + route="contestacao_agent", intent="contas_vas_cancel", + reason="human_retention_cancel_accepted", + patch={**reset_patch, "mcp_tools": ["consultar_vas", "cancelar_vas_avulso"], "context": context, + "_route_metadata": {"contextual_reentry": True, "original_input": semantic_request, + "relevant_conversation_context": "Serviços avulsos comprovados na variação: " + ", ".join(names)}, + "contas_retention": {"pending_stage": None, "stages_offered": offered, "items": retained_items}}, + ) + if answer_kind == "NO" or _HUMAN_RE.search(text): + return PolicyDecision( + route="human_handoff", intent="human_handoff", reason="human_retention_declined", + patch={**reset_patch, "contas_retention": {"pending_stage": None, "stages_offered": offered, "items": retained_items}}, + ) + + if state.get("route") == "human_handoff" and "explain" not in offered: + items = _retention_items(state) + if items: + return PolicyDecision( + route="conversation_policy_response", intent="contas_retention_explain", + answer="Antes de transferir, identifiquei serviços avulsos que participaram da variação da sua conta. Posso primeiro explicar essa variação para você?", + reason="human_retention_offer_explain", + patch={**reset_patch, "human_handoff_requested": False, "session_control": "", + "contas_retention": {"pending_stage": "explain", "stages_offered": ["explain"], "items": items}}, + ) + + if reset_patch: + return PolicyDecision(patch=reset_patch) + return None diff --git a/app/domain/contas/integrations/__pycache__/secure_pdf_crypto.cpython-313.pyc b/app/domain/contas/integrations/__pycache__/secure_pdf_crypto.cpython-313.pyc index 420fc86efd025e0fe5478e47ac1bc3e1e4888059..a76bd2bab60db4b3d924bbd671aebab10a88ea7b 100644 GIT binary patch delta 20 acmZ1_yh@n+GcPX}0}${no4S#EJ|_S;8wE-L delta 20 acmZ1_yh@n+GcPX}0}!mbIB6sId`M()qNyj%=Gz`tzjM(zzU09N=19{>OV delta 22 ccmdnJlX3S>M()qNyj%=Gu(^b diff --git a/app/extensions/__pycache__/tim_judges.cpython-313.pyc b/app/extensions/__pycache__/tim_judges.cpython-313.pyc index 017cdc754ef6ea4de325f2d8322fe009e034083e..17ccdc3aa3a56dd9116fb3fbe5e9cb3280a95307 100644 GIT binary patch delta 20 acmaE-^-hcXGcPX}0}${no4S!ZSrh<80|n3k delta 20 acmaE-^-hcXGcPX}0}!mbIB6qyvM2ybItG*g diff --git a/app/extensions/tim_prompts/__pycache__/__init__.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/__init__.cpython-313.pyc index dcb0854551f8ac8ef158c1771ee0c79e4e168fc9..1446445474168cb94443f45b2adae5be2541ca6d 100644 GIT binary patch delta 19 ZcmZ3>xR#OoGcPX}0}${nn>vwu5dbiJ1qJ{B delta 19 ZcmZ3>xR#OoGcPX}0}!mbIB6pHA^GcPX}0}${no4S$vr33&+@&GcPX}0}!mbIB6sIO9=o?DF-(I diff --git a/app/extensions/tim_prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/ausencia_oferta_proativa.cpython-313.pyc index 7183c9531ef4eb59cdbe82e7d20c1d4c2717f08f..672838175e71048838fe3c6accdb81b1603d097f 100644 GIT binary patch delta 20 acmccQbIFJMGcPX}0}${no4S$PT@3(5d)S delta 20 acmaEE_1ud4GcPX}0}!mbIB6qyj4S|4Y6hnO diff --git a/app/extensions/tim_prompts/__pycache__/out_of_scope.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/out_of_scope.cpython-313.pyc index 0a7201a9ef7e80a0b3f10ba3c95d8cff5a86ffe5..a2da2611e18257b9ee1f134d92fb2a88e52c2edd 100644 GIT binary patch delta 22 ccmey}!uY#|k^3_*FBbz4@GYCVk-NYN09b?u+5i9m delta 22 ccmey}!uY#|k^3_*FBbz4thzX9BX@xl0A0HWo&W#< diff --git a/app/extensions/tim_prompts/__pycache__/revprec.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/revprec.cpython-313.pyc index 0478eca37d68119c96ee2ccade4030c50e336349..713221a4f429b16351caf482dae0ef911e4881c1 100644 GIT binary patch delta 20 acmaE({YIPnGcPX}0}${no4S$vp(p@F*9J@g delta 20 acmaE({YIPnGcPX}0}!mbIB6sILs0-r4hIkb diff --git a/app/extensions/tim_prompts/__pycache__/rqlt.cpython-313.pyc b/app/extensions/tim_prompts/__pycache__/rqlt.cpython-313.pyc index 54e04f28d19b22b0298717eba16a8532a89f2ef7..4fda7afd0b447db8a669d8b0d805f39e6760293d 100644 GIT binary patch delta 20 acmX@kah!wuGcPX}0}${no4S$Ph6MmR5(NeT delta 20 acmX@kah!wuGcPX}0}!mbIB6rd4GRE2Nd?LP diff --git a/app/observability/__pycache__/__init__.cpython-313.pyc b/app/observability/__pycache__/__init__.cpython-313.pyc index 2c1853349a96bbac587889ec8141d4fbf8d33925..4fe4eea7459e585df1249b390eda01484ddb4c0b 100644 GIT binary patch delta 19 ZcmZ3&xP+1WGcPX}0}${nn>vwuCIBxl1nU3* delta 19 ZcmZ3&xP+1WGcPX}0}!mbIB6pHOaL>Y1+M@A diff --git a/app/observability/__pycache__/telemetry_observer.cpython-313.pyc b/app/observability/__pycache__/telemetry_observer.cpython-313.pyc index def8ec7988a9b2eda8c4d1b7fc5557f1ece2780a..55420615d4149c1808b8f38e89edf2b827244ef2 100644 GIT binary patch delta 20 acmeyZ_FIknGcPX}0}${no4S#^Ko|f~1;qdW diff --git a/app/presentation/__pycache__/tool_renderers.cpython-313.pyc b/app/presentation/__pycache__/tool_renderers.cpython-313.pyc index cf7326b8c3dab7e7badf792196bb6356bc086db0..c4c0123ffefee83dd5ef54b5d29854d910ab9659 100644 GIT binary patch delta 20 acmdn0wN;DzGcPX}0}${no4S!(OB4V+8wDi* delta 20 acmdn0wN;DzGcPX}0}!mbIB6rdmM8#0QU&P% diff --git a/app/state.py b/app/state.py index 7122992..1bed096 100644 --- a/app/state.py +++ b/app/state.py @@ -62,3 +62,9 @@ class AgentState(TypedDict, total=False): long_term_memory_load_error: str operational_context_boundary_pending: bool operational_context_reset: bool + no_match_count: int + contas_retention: dict[str, Any] + regulatory_context: dict[str, Any] + terminal_status: str + conversation_terminal_message: str + diff --git a/app/workflows/__pycache__/agent_graph.cpython-313.pyc b/app/workflows/__pycache__/agent_graph.cpython-313.pyc index f2ff450077cf7480de7f1ab86ba19999dfe16b5e..7a62a87a3e0924ea795d91f0a1252fbb8d6b68b6 100644 GIT binary patch delta 9010 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 delta 19 ZcmbQsIG2(8GcPX}0}yz{Oq$3&2>>n@1jPUV diff --git a/contas_mcp/servers/__pycache__/__init__.cpython-313.pyc b/contas_mcp/servers/__pycache__/__init__.cpython-313.pyc index 635bb830427cff893d01cda9dc640990f16b0ace..403be7b46120a3ab1156b6abdb3be99f013f5e81 100644 GIT binary patch delta 19 ZcmZ3=xRjCmGcPX}0}u!-n>vwu7630`1n>X= delta 19 ZcmZ3=xRjCmGcPX}0}yz{Oq$3&3ji-Z1l<4t diff --git a/contas_mcp/servers/contas_mcp_server/__pycache__/__init__.cpython-313.pyc b/contas_mcp/servers/contas_mcp_server/__pycache__/__init__.cpython-313.pyc index cdf344ee6a6d38e07b31f762f833e9145454acc6..bf41d42f3315f3dd4cdee769153b41c91f54921e 100644 GIT binary patch delta 19 ZcmdnaxSf&vGcPX}0}u!-n>vwu4FECv1ttIh delta 19 ZcmdnaxSf&vGcPX}0}yz{Oq$5O1^_YG1rq=O diff --git a/contas_mcp/servers/contas_mcp_server/__pycache__/authorized_lines_service.cpython-313.pyc b/contas_mcp/servers/contas_mcp_server/__pycache__/authorized_lines_service.cpython-313.pyc index f66c7781703d16c63c9f051aa67b42f00464ad59..28a0d79d2348fb7ffab0dd2d843f3018e10bf9c5 100644 GIT binary patch delta 20 acmX@Ec3h47GcPX}0}u!-o4S$PMi>A-X9ZIL delta 20 acmX@Ec3h47GcPX}0}yz{Oxnn8BMbmOG6g^Y diff --git a/contas_mcp/servers/contas_mcp_server/__pycache__/discount_history_service.cpython-313.pyc b/contas_mcp/servers/contas_mcp_server/__pycache__/discount_history_service.cpython-313.pyc index 63d5cc183f8289109b6d94993900e30dc96048bc..e9abe151b8d75ddc4cd74a0f770e546248d56380 100644 GIT binary patch delta 20 acmeBI>sRCc%*)Hg00aWdrf%eB5e5J?rv$42 delta 20 acmeBI>sRCc%*)Hg00dq!lQwd*2m=5$as-$F diff --git a/contas_mcp/servers/contas_mcp_server/__pycache__/line_policy.cpython-313.pyc b/contas_mcp/servers/contas_mcp_server/__pycache__/line_policy.cpython-313.pyc index 8cde6faed114510493c9d55ff05f30c09c08bdcb..73f0215b165869b77cefbe251737e61a4c9a4198 100644 GIT binary patch delta 20 acmZpWXprFk%*)Hg00aWdrf%f^$_)TBPX$^4 delta 20 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 delta 7394 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 m dict[str, Any] | None return None if bool(args.get("clarification_resolved")): return None + + # A pre-validation transaction boundary may already have resolved a multi-item + # cancellation into authoritative ``items[]``. At execution time that list is + # the source of truth; re-parsing the presentation ``subject`` (for example + # ``"Tamboro Mensal, Paramount+"``) would incorrectly turn two canonical + # entities back into one ambiguous free-text reference. + if name == "cancelar_vas_avulso": + resolved_items = [ + item for item in (args.get("items") or []) + if isinstance(item, dict) and str(item.get("name") or item.get("subject") or "").strip() + ] + if len(resolved_items) >= 2: + return None msisdn = str(args.get("msisdn") or "").strip() subject = str(args.get("subject") or "").strip() if not msisdn or not subject: @@ -986,6 +999,49 @@ async def _validate_contestation(args: dict[str, Any]) -> dict[str, Any]: "entity_resolution": "invoice_evidence", }, } + + # A claimed amount larger/different from the authoritative billed amount is + # recoverable input, not a reason to emit a generic safety failure. Keep the + # subject frozen and recollect only ``valor``, while telling the customer the + # concrete amount found in the invoice evidence. + amount_mismatch = next(( + entry for entry in (validation_log or []) + if isinstance(entry, dict) and str(entry.get("erro") or "") in { + "valor_ajuste_maior_que_item", "valor_ajuste_divergente_item" + } + ), None) + if amount_mismatch is not None: + billed = amount_mismatch.get("valor_item_fatura") + canonical_subject = str( + amount_mismatch.get("item_fatura_resolvido") + or args.get("resolved_subject") or args.get("subject") or "item" + ).strip() + billed_ptbr = _money_ptbr(billed) if billed not in (None, "") else "" + message = ( + f"O valor encontrado na fatura para {canonical_subject} é R$ {billed_ptbr}. " + f"O valor informado (R$ {_money_ptbr(requested_value)}) não corresponde a essa cobrança. " + "Informe o valor da cobrança que deseja contestar." + if billed_ptbr else + "O valor informado não corresponde à cobrança encontrada na fatura. Informe o valor correto da cobrança que deseja contestar." + ) + return { + "eligible": False, + "status": "NEEDS_PARAMETER", + "parameter": "valor", + "reason": "CVAL", + "recoverable_reason": "amount_not_supported_by_invoice", + "subject": canonical_subject, + "resolved_value": billed, + "parameter_message": message, + "validation_log": validation_log, + "items": validated, + "metadata": { + "side_effect_free": True, + "target_tool": args.get("target_tool") or "contestar_cobranca", + "guardrail_code": "CVAL", + "entity_resolution": "invoice_evidence", + }, + } return { "eligible": False, "status": "BLOCKED", @@ -1145,14 +1201,79 @@ def _vas_domain_policy_from_invoice_detail(canonical: str, args: dict[str, Any]) return "", item_type +def _resolve_multiple_vas_subjects(subject: str, catalog: list[dict[str, Any]], args: dict[str, Any]) -> list[dict[str, Any]]: + """Resolve explicit multi-entity cancellation references against authorized evidence. + + Named references are split into conversational segments and each segment must + resolve uniquely through the same catalog resolver used for single entities. + Explicit mass expansion is restricted to "todos os VAS/serviços avulsos"; + generic "todos" is deliberately not expanded. + """ + raw = str(subject or "").strip() + norm = _norm_entity_reference(raw) + if not norm: + return [] + explicit_all_avulso = any(token in norm for token in ( + "todos os vas avulsos", "todos vas avulsos", "todos os servicos avulsos", + "todos servicos avulsos", "todas as assinaturas avulsas", + )) + selected_names: list[str] = [] + if explicit_all_avulso: + selected_names = [str(row.get("name") or "").strip() for row in catalog if row.get("name")] + else: + cleaned = re.sub(r"(?i)\b(cancelar|cancela|cancele|retirar|retire|tirar|tire|desativar|desative)\b", " ", raw) + segments = [seg.strip(" .:-") for seg in re.split(r"\s*(?:,|;|/|\be\b|\bmais\b)\s*", cleaned, flags=re.I) if seg.strip(" .:-")] + if len(segments) < 2: + return [] + for segment in segments: + canonical, _ = _resolve_catalog_entity(segment, catalog) + if canonical: + selected_names.append(canonical) + selected: list[dict[str, Any]] = [] + for name in list(dict.fromkeys(selected_names)): + resolved_class, resolved_type = _vas_domain_policy_from_invoice_detail(name, args) + if explicit_all_avulso and resolved_class != "cancelar_vas_avulso": + continue + selected.append({ + "name": name, + "msisdn": _invoice_detail_msisdn(args.get("invoice_detail"), name) or str(args.get("msisdn") or ""), + "tool_category": resolved_class or None, + "item_type": resolved_type or None, + }) + return selected + + async def _validate_vas_subject(args: dict[str, Any]) -> dict[str, Any]: """Side-effect-free entity resolution used before confirmation/execution.""" await _enrich_invoice_context("validar_vas_subject", args) subject = str(args.get("subject") or "").strip() catalog = _vas_entity_catalog(args) canonical, matches = _resolve_catalog_entity(subject, catalog) + requested_tool = str(args.get("target_tool") or "").strip() + multi = _resolve_multiple_vas_subjects(subject, catalog, args) if requested_tool == "cancelar_vas_avulso" else [] + if len(multi) >= 2 or (multi and any(token in _norm_entity_reference(subject) for token in ("todos os vas avulsos", "todos os servicos avulsos"))): + names = [str(item.get("name") or "").strip() for item in multi if item.get("name")] + return { + "eligible": True, + "status": "ELIGIBLE", + "subject": subject, + "resolved_subject": names[0] if len(names) == 1 else ", ".join(names), + "resolved_subjects": names, + "entity_resolution": "vas_evidence_multiple", + "transaction_decision": { + "resolved_arguments": {"subject": ", ".join(names), "items": multi}, + "target_tool": requested_tool, + "action_changed": False, + "requires_reconfirmation": False, + "confirmation_message": ( + f"Você confirma o cancelamento dos serviços {', '.join(names)}? " + "Responda 'sim' para executar ou 'não' para cancelar." + ), + "domain_policy": {"class": "cancelar_vas_avulso", "item_type": "multiple"}, + }, + "metadata": {"side_effect_free": True, "target_tool": requested_tool, "catalog_size": len(catalog), "resolved_count": len(names)}, + } if canonical: - requested_tool = str(args.get("target_tool") or "").strip() effective_tool = requested_tool resolved_class = "" resolved_type = "" diff --git a/docs/FIX_CONTAS_REPORT_20260831_SECOND_PASS.md b/docs/FIX_CONTAS_REPORT_20260831_SECOND_PASS.md new file mode 100644 index 0000000..58be391 --- /dev/null +++ b/docs/FIX_CONTAS_REPORT_20260831_SECOND_PASS.md @@ -0,0 +1,27 @@ +# Correções após regressão de 31/08/2026 + +Esta rodada corrige quatro comportamentos observados no relatório de regressão sem reintroduzir o runtime conversacional legado. + +## 1. Cancelamento múltiplo após confirmação + +O snapshot transacional do framework já preservava corretamente os argumentos confirmados. O defeito estava no preflight de execução do MCP do Contas, que tentava resolver novamente o `subject` de apresentação (por exemplo, `Tamboro Mensal, Paramount+`) mesmo quando `items[]` já continha múltiplas entidades canônicas pré-validadas. Agora `items[]` é a fonte de verdade nessa condição e não há segunda resolução textual. + +## 2. Contestação com valor incompatível + +Uma divergência de valor comprovada pelo CVAL passa a ser recuperável: o item permanece preservado, apenas `valor` volta para coleta e a resposta informa o valor autoritativo encontrado na fatura. O contrato de auditoria mantém `reason=CVAL` e acrescenta `recoverable_reason=amount_not_supported_by_invoice`. + +O runtime genérico ganhou suporte opcional a `parameter_message` emitido por um pre-validator de domínio. O framework apenas apresenta essa mensagem enquanto permanece em `COLLECTING_PARAMETERS`; ele não interpreta a regra de negócio. + +## 3. Encerramento explícito + +Expressões inequívocas como `entendi, obrigado, era só isso` encerram a sessão como `resolvido`, desde que não exista transação ou workflow ativo. Isso evita que uma despedida caia em fallback/guardrail sem consumir confirmações pendentes. + +## 4. Continuação plural após explicação de fatura + +Frases como `as duas mesmo, pode seguir` imediatamente após `contas_invoice_explanation` permanecem no contexto de explicação e não são confundidas com finalização genérica. + +## Regressão + +- Testes novos e direcionados: 58/58 no Contas e 30/30 no runtime transacional do framework. +- `tests/migration`: 818 PASS / 2 FAIL. +- Os 2 FAIL restantes são preexistentes nesta base: caso histórico de `validar_contestacao` com TIM Fashion/R$50 e fraseologia de `termino_desconto`. diff --git a/docs/FIX_CONTAS_RESIDUAL_CONVERSATION_PARITY_20260831.md b/docs/FIX_CONTAS_RESIDUAL_CONVERSATION_PARITY_20260831.md new file mode 100644 index 0000000..c86dc15 --- /dev/null +++ b/docs/FIX_CONTAS_RESIDUAL_CONVERSATION_PARITY_20260831.md @@ -0,0 +1,63 @@ +# Correção de paridade conversacional residual do Contas — 2026-08-31 + +## Escopo + +Correções pontuais extraídas do comportamento útil do Contas anterior sem restaurar o runtime legado: + +- retenção antes de handoff humano; +- jurídico/Anatel/Procon com dependência de entidade previamente em foco; +- três falas consecutivas realmente incompreensíveis; +- preservação do pós-finalização no framework, com status terminal de erro respeitado; +- cancelamento múltiplo por entidades nomeadas/contextuais e por "todos os VAS avulsos". + +## Arquitetura + +Foi adicionada `app/domain/contas/conversation_policy.py`, executada depois do `EnterpriseRouter` e antes do agente de domínio. A policy não executa side effects: apenas reprompta, enriquece contexto ou altera o roteamento. Toda operação transacional continua passando pelo `AgentRuntimeMixin`, pré-validação MCP, confirmação explícita e workflow do Contas. + +## Retenção + +Quando o router solicita handoff humano, a policy procura evidência autoritativa de VAS avulso que participou da variação da conta usando `varied_avulso_items`. Sem evidência, o handoff segue normalmente. Com evidência, a policy oferece dois degraus: explicação da variação e, em seguida, tratamento dos VAS identificados. Recusa do segundo degrau leva ao handoff humano normal. + +O aceite do tratamento cria reentrada contextual com os nomes já comprovados; o cliente não precisa repeti-los e a transação continua sujeita à pré-validação e confirmação. + +## Jurídico / Anatel / Procon + +A mera ameaça regulatória não cria uma transação. Sem entidade concreta em foco, a fala é encaminhada como reclamação ampla ao suporte, sem MCP transacional. Quando já existe `subject/items` em estado transacional, o foco é preservado e a fala pode continuar no fluxo correspondente. A fatura inteira nunca é usada para inventar o alvo. + +## Três falas incompreensíveis + +Foi criada a intent semântica `contas_no_match`, exclusiva para fala sem conteúdo recuperável. `fallback` genérico não conta como incompreensão. O contador é consecutivo e reinicia em qualquer turno compreendido. + +- 1ª: pede reformulação; +- 2ª: pede reformulação; +- 3ª: encerra pelo nó global `end_session`, chamando `finalizar_atendimento` com `status=erro_no_match`. + +O limite pode ser configurado por `CONTAS_NO_MATCH_MAX_CONSECUTIVE`, default 3. + +## Cancelamento múltiplo + +`validar_vas_subject` agora resolve múltiplas entidades exclusivamente contra catálogo autorizado VAS/fatura. Exemplos suportados após extração semântica contextual: + +- `cancela Netflix e HBO`; +- `os dois` / `ambos`, quando o extrator LLM consegue resolver os nomes pelo contexto imediato; +- `todos os VAS avulsos`. + +`todos` genérico não expande em massa. Para "todos os VAS avulsos", itens estratégicos/bundle são filtrados pela política de domínio. Os itens resolvidos são enviados como `items[]` para o workflow batch existente, com uma única confirmação explícita antes da execução. + +## Pós-finalização + +Não foi criado runtime duplicado. O lifecycle continua no framework. O nó `end_session` passou apenas a respeitar um `terminal_status` já definido pela policy (por exemplo `erro_no_match`) e uma mensagem terminal específica, mantendo o mecanismo atual de replay/soft reset. + +## Testes + +Novos testes: + +- `tests/migration/test_contas_conversation_policy_residuals.py`; +- `tests/migration/test_multiple_vas_subject_resolution.py`. + +Regressão direcionada: **61 PASS**. + +Regressão completa `tests/migration`: **810 PASS / 2 FAIL**. Os mesmos dois FAIL foram reproduzidos no ZIP original sem estas alterações, portanto são falhas preexistentes e fora do escopo desta correção: + +1. `test_validar_contestacao_aprova_quando_item_e_valor_sao_comprovados`; +2. `test_termino_desconto_e_valor_divergente_preservam_semantica_do_original`. diff --git a/tests/migration/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/conftest.cpython-313-pytest-9.0.2.pyc index 18dcdb9e1cb9d96f4501804b97fb30ab543e2005..6307e1611fffc6aba8d6b1db09965a46cdde2664 100644 GIT binary patch delta 71 zcmdnVc9o6mGcPX}0}zN_*~pd5r0=Dln^&Trl30?cpPZjpl2{y{ms+l$n4X$f5)T!~ UPtJ@lNzEb85WTXI>jATVq<(H*iGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz5y&=GUhIyT2T4 delta 46 zcmZo!!2Du9GuLNcUM>b8u#4Hq^?+H}RzEkdL_a05BvC&tv%<(IzRYB^B+Kj507>)@ A3jhEB diff --git a/tests/migration/__pycache__/test_backend_wrapper_contract_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_backend_wrapper_contract_parity.cpython-313-pytest-9.0.2.pyc index 54e163532f9ddb6c1dfaf40f22474feeca9c2384..9ba7c9a2f37f5cd921ace97b85994761a32e045f 100644 GIT binary patch delta 74 zcmZ3olCEI>oAkBmws+uiGE6ANuqvQW`&Vae3{ASKTJpZ0ZZc# Ac>n+a diff --git a/tests/migration/__pycache__/test_business_events_and_guardrails.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_business_events_and_guardrails.cpython-313-pytest-9.0.2.pyc index aa5cfaab434ce8d0c868b2066596559ebcc1d175..f100c2e564c5ec5a587f1334afd71796358f99be 100644 GIT binary patch delta 72 zcmbQQxLc9yGcPX}0}zN_*~qnrQ9o5bH?KrLC9xz?KRG|IB(XR?FST4hF+DY}Bpxb| VpPU(AlA2qPlUS0v`6lBrJ^*9n8Z`g_ delta 44 ycmdn3IA4+LGcPX}0}$B7Y~b85WTXI%Y<1!ML##ML_a05BvC&(Kd&UQI6g16Tt6{AHLoNd XDv+O?8DEl`Tac4jlDavN*(whJs0SKa delta 46 zcmZ4fn6djYBiCnMUM>b8u#4HqWx_1%p`V*qqMwpjlBl1SSz%-pUuLp7m)R;007X^} A_y7O^ diff --git a/tests/migration/__pycache__/test_cancel_composite_workflow.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_cancel_composite_workflow.cpython-313-pytest-9.0.2.pyc index 935d8b3f6da0733eff00aa30bf549499d9c9ac94..7251d60d64d23c5f9e3fe804393af9551628184c 100644 GIT binary patch delta 74 zcmZ2>jrq_uX0Fe?yj%=GAbMpZ*EMGS1pVB+68)6Kl0^OF{JfIH;`qGOa{a{g)Vz{- Xs6c*lW_(F%Zb43BN$Td$%*M|F)*2iv delta 46 zcmX?fjd|HMX0Fe?yj%=GU>CEI>l(ALi+*liiGE6ANuqvQW`&Vae3{8+eiq~B09vFD A%K!iX diff --git a/tests/migration/__pycache__/test_cancel_wrapper_remaining_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_cancel_wrapper_remaining_parity.cpython-313-pytest-9.0.2.pyc index 95c5d4acdf3ee8577755f938dc55962c38aeab32..e506ba17ca99bb5b1f715e54b06358b9fc600f94 100644 GIT binary patch delta 74 zcmZ3!o9XawCa%xCyj%=GAbMpZmnVyUntpCxiGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz1Edi{nfHr^yCEI%acXeOFuWSL_a05BvC&tv%<(IzRYBE6N}?a07T#p ALI3~& diff --git a/tests/migration/__pycache__/test_contas_conversation_policy_residuals.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contas_conversation_policy_residuals.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..c18630d45e5d9b5cb6c19e41a58837f3403b865a GIT binary patch literal 30003 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 delta 46 zcmX^8jd}eyX0Fe?yj%=GU>CEION&R?RzEkdL_a05BvC&tv%<(IzRYBEGS7>509l+5 AivR!s diff --git a/tests/migration/__pycache__/test_contas_invoice_explanation_routing.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contas_invoice_explanation_routing.cpython-313-pytest-9.0.2.pyc index 666add57df13425fe45f014396480497dc6fa2a0..89727621b606dc485b39ecab5c83f34e6f85946b 100644 GIT binary patch delta 74 zcmdnl#(1@jk?S)rFBbz4h+f&q^^s9OQ$IJaL_a05BvC&(Kd&UQI6g16Tt6{AHLoNd XDv+O?8DEl`Tac4jlDe6XN!t+swfh=8 delta 46 zcmccG#<;VMk?S)rFBbz4*u`w*`p78ktDl=!qMwpjlBl1SSz%-pUuLpdi%HuN07#Mz A+5i9m diff --git a/tests/migration/__pycache__/test_contestation_business_rules_full.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contestation_business_rules_full.cpython-313-pytest-9.0.2.pyc index ed16df81591a83d6ee08fd9ad464a9dc2a6c84d4..987391d2ce973fc5e3eec29d857c1c2b1a9450ef 100644 GIT binary patch delta 74 zcmeC*%D8$fBiCnMUM>b85WTXIYcG?2x_)k6iGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz5yGrmf)sv2GiE delta 46 zcmZ3zm9c*-BiCnMUM>b8u#4HqwUR!O07$tH A8vpnU|M~0SN43HgYXx6n59o%`4GQNi0d!Ps^+@GKw!V*?f;tO9lWT2@PZb diff --git a/tests/migration/__pycache__/test_contestation_prompt_terminal_out_of_scope.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_contestation_prompt_terminal_out_of_scope.cpython-313-pytest-9.0.2.pyc index dfed7068f4839bfe2dae546acaedb2f7990dd777..72822fb05be529f05ac61365480a7fb28f2efbeb 100644 GIT binary patch delta 72 zcmZ24eOj99GcPX}0}zN_*~k^irC*?*n^&Trl30?cpPZjpl2{y{ms+l$n4X$f5)T!~ VPtJ@lNzEtyw;(66Bz1En=Y2N-pfeiA delta 46 zcmcbzfN{qHMy}7iyj%=GU>CEI%Z5|fT|YOkL_a05BvC&tv%<(IzRYBEDd&AR06^vr AWB>pF diff --git a/tests/migration/__pycache__/test_dispute_actions_remaining_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_dispute_actions_remaining_parity.cpython-313-pytest-9.0.2.pyc index 13721774b1e67d69d3035c883a55f576ccd3230f..542dcc5ad8a4fe7774765a817a70ffd940d3bdd9 100644 GIT binary patch delta 74 zcmbQ#!?>=8k?S)rFBbz4h+f&qCBUSguAiG%qMwpjlBl1YpI4Gt9G{n3uAi8mnpYAJ X706G{j4w&eEyzhMN!_f=^wb#ubf+2f delta 46 zcmZ42!#Jsjk?S)rFBbz4*u`w*5?~Vc*3Zo=(N9S%Nz_lvtS~Z)FEiQf$@J7204FXD AkpKVy diff --git a/tests/migration/__pycache__/test_external_guardrails_judges_spi.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_external_guardrails_judges_spi.cpython-313-pytest-9.0.2.pyc index 1dd140d7d21b21fe9511c4b257fb1bbcf16ce501..de91aa049643ecaf6b855c8cfc5795abe64f40ff 100644 GIT binary patch delta 72 zcmeD5U+T~GnU|M~0SH8|Y~*6)(@)jU%`4GQNi0d!PtMOPNi2@fOD)$=Oi#@#iH8d0 VCuhc&q~;dnB$lLZR^m&S1OQ0g7`*@h delta 44 ycmZ4L-|5fwnU|M~0SN43Hgd7@347}2=9TEDB$g!Vr)5?c8O4{GY_{V|mjnO`>w;(66Bz5ytrpeO*uG$+v delta 46 zcmX@Ig=xhWCa%xCyj%=GU>CEItAa_`T|YOkL_a05BvC&tv%<(IzRYCvMyAQr0Z6G1 A-2eap diff --git a/tests/migration/__pycache__/test_framework_agent_gap_fixes.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_framework_agent_gap_fixes.cpython-313-pytest-9.0.2.pyc index 956fe7462c373632bb4ef2586546c6f11ebf9273..8a8dd2d7e0f93adcc805ddb6e3723e1c9e572324 100644 GIT binary patch delta 72 zcmbPZy2F&~GcPX}0}zN_*~nGJuAiWvn^&Trl30?cpPZjpl2{y{ms+l$n4X$f5)T!~ VPtJ@lNzE(gjGcPX}0}$B7Y~-q97k1Il%`4GQNi0d!Ps^+@GKw!V*}R#ZRTuyib85WTXID}q%&Q9n1YL_a05BvC&(Kd&UQI6g16Tt6{AHLoNd XDv+O?8DEl`Tac4jlDfH+b*2jdhEEzm delta 46 zcmZ2Ag|Tl6BiCnMUM>b8u#4Hq6~QX(s-K%zqMwpjlBl1SSz%-pUuLp-BI`^S05EC| A-T(jq diff --git a/tests/migration/__pycache__/test_framework_rag_directive.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_framework_rag_directive.cpython-313-pytest-9.0.2.pyc index e6a2eac97e056f3ec576d19f2e8724055cb67e19..d4fd0b4235c2fd0cea9e216d0a1b72bc842e63bf 100644 GIT binary patch delta 72 zcmaFn+2qCbnU|M~0SH8|Y~*5Q(vQ>6%`4GQNi0d!PtMOPNi2@fOD)$=Oi#@#iH8d0 VCuhc&q~;dnB$lLZR$w}&1OQU088H9= delta 44 ycmZqjdgjUXnU|M~0SN43HgYjD2|MZM=9TEDB$g!Vr)5?c8O4{GY_?%KrUU>G;tbCK diff --git a/tests/migration/__pycache__/test_framework_zero_legacy.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_framework_zero_legacy.cpython-313-pytest-9.0.2.pyc index b5e5f7baf70ade065eccec8a436f0d4dae9e6772..b324c3d1a5874a2b321c62347d9a6946203caa50 100644 GIT binary patch delta 72 zcmey$JCTp;GcPX}0}zN_*~s;XML$MAH?KrLC9xz?KRG|IB(XR?FST4hF+DY}Bpxb| VpPU(AlA2qPlUS0v`9I4yMgVQu8m0gM delta 44 ycmbQp_m!9HGcPX}0}$B7Y~*^xBJ7}_n^&Trl30?cpO#r+WE5X!vRRt-8zTT2i48>n diff --git a/tests/migration/__pycache__/test_guardrail_binary_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_guardrail_binary_parity.cpython-313-pytest-9.0.2.pyc index ac2e807e9ecfefeb94a102ff3afb412945074740..6453b1de1df9fc1ee85038161083e339af2903b2 100644 GIT binary patch delta 72 zcmdlUe>tA(GcPX}0}zN_*~pd0q#viBn^&Trl30?cpPZjpl2{y{ms+l$n4X$f5)T!~ VPtJ@lNzE6UM>b85WTXItCK}PT|YOkL_a05BvC&(Kd&UQI6g16Tt6{AHLoNd XDv+O?8DEl`Tac4jlDc^r%f7_`!p|Gg delta 46 zcmZp;$n@j_6W3>6UM>b8u#4Hq)yX34t)H7$qMwpjlBl1SSz%-pUuLrT5X-*B08>E^ AZvX%Q diff --git a/tests/migration/__pycache__/test_invoice_explanation_final_response.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_invoice_explanation_final_response.cpython-313-pytest-9.0.2.pyc index 30ec2dcde0fe0dd91120c0439ae3ec4730bd75e0..661455f73e5ce6565d4b660007a326de6fe67add 100644 GIT binary patch delta 72 zcmX@0d`Fqb85WTXI%ZXh-UOzXlL_a05BvC&(Kd&UQI6g16Tt6{AHLoNd XDv+O?8DEl`Tac4jlDavboi!K$pNbj& delta 46 zcmZqJ%J^gpBiCnMUM>b8u#4Hq<-{)Rte=}#qMwpjlBl1SSz%-pUuLqonw>Qm06wG* AoB#j- diff --git a/tests/migration/__pycache__/test_mcp_contestation_subject_guard.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_mcp_contestation_subject_guard.cpython-313-pytest-9.0.2.pyc index 43095bdcdbf0318ad44efe5e1dbfd9693ee0e1a4..80e4baecadba0f0fa19403cea51451198da01868 100644 GIT binary patch delta 74 zcmdnDit*MeMy}7iyj%=GAbMpZS0J-~s(x->iGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz1Eh^MybFtpytb delta 46 zcmcb$igDj6My}7iyj%=GU>CEIE09^(Q$IJaL_a05BvC&tv%<(IzRYBE7xRTc07zU8 Apa1{> diff --git a/tests/migration/__pycache__/test_multiple_vas_subject_resolution.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_multiple_vas_subject_resolution.cpython-313-pytest-9.0.2.pyc new file mode 100644 index 0000000000000000000000000000000000000000..3b1c5c19e940879642bff257cf95cd321b5a0c4a GIT binary patch literal 5074 zcmcIo&2QYs6(4fBpIohEyYW}!gjH?FjO|@Xmh9NI3_Ff(*^Z=0^cs%sf}nP(H61Rw z8FD3CZU7y62#Q<{q(u)sO8-Hx?Ma6oD9MFVB0!7w)LR<$QUeA0-VC|BlD1Z2AjIm; zn>TMBXWl%%-#l&h^yCOUzxw?7Au!L0Ml|6zp#p2gTM188$SsK` z6+V)psfVfQLOi+M_7hDU5qO_ww8UXTvzi1nrzL^PH9<}N6Ne`j)Qao)hNssnjiP7L zIg@(Dwn*oqV%@NuN@S3kO#{WnZvGvluuwr02LzxAMx_CvlyHPHneLp!CKB>Mj2NON zwbWrU5^Y)`yXvR4Os9U^(sVMm*>1ILSkK6?}mWT)380^A5qX{_q zBXK-Sh)fjXNKQf%wM0pD@061l#z1HGL}a$=!usLR_%oe}xpoV#&zDofg4T2I+ORkx z@sW->?C{(A$n}%56d%{Fn#ovGD-^}kuofq+^=f_P^nk#6nFl?w^$uHIgQT2^ZN;q# zp*AWw(x}idYv3aV{+z@tQTI%Ql4I1(mxT$_pS7(g%DCxxhP}`?_Wq7@OASE1c1X1 zeK{M-b=UdCeA+Pl%A+tHom7~#AWpnccoNF+LY=RCptEzPvopjy`~@SOopT;~Rf!+w z@$kay2M&D?%wcZw{sd%^eATxgVObtbTEBCcxVMvkJs~`EMEJ| z+eg>sW4~#B`IFCQzqtA9W*|)l^0DCE3&F*SK%K;{I=L!OZb;E@jVbW%iw=IBX|~i_ z4Cwr4O+Mz~uKsYSaP^e51%xn_G7$Oz=vELaiQfT!Bt*j)9Fz`Vn#LTm?QujcIlo)ln>Z4m4_tK7PO?5dfF?P|I2 zweufuS$o%=mxb7NYsdSy%<8`O)-2d*ZrAm9gYNEjThP6$%~ZT@O)jQ6tZR9#r<{pE zKKlTXkv$!@FfVU=;A)YLZN+T_@*)6zf`h%21i+uG5w$SEK!76JP&{Ia7rj@b3dJ;RDPI?HK*wkEYIy6;w9yb73}?zk-F!o5MSLmq{kjmQoVjCi^O2GOS!x6SdV zC&nLUkRE{nRalrucsZ|nxn~ihaKsskMZiR&0o5zM8d7qforuut6oaM_)#J=L)l+ky z#b`DNHt9RKumM~|8sTdI$q?-a0dgZq&LKG;N&tI93%wnXHwbvh#KWpgkE0=G4P%z7 zNZv&=d4!vprUlm!#|u;ZmJlA)y+>}-t}?9CYqmRM*gD=f=t-P;3dw08YL1qW$0c^+ z(;yw*COO+V{2qTTU+m!EmfisGacCPnv!yrUVG@h6O;I?y4Zlt#&~dQDBJ01vY{Rv& z;N;DqaH~6>eJvL@2QOSanX!2lTKBQSHxZ7Ff)g*5g1`IZbO#yyz0BDUtW-Uv2UXiLA7S(Bz%wDxybkm9Sx8gxuLMZ(P9)oz&~b$x zCZ$F44I!7s4@79j#7PlKoXgNau>*n!!aT~$B5Sb6z5@CNOxy*S4uA?@{~>%8uLe6R zn>!$7I&hVUP~}aIDyG6vMR7d^9Ukq9zKMER*)X`FaQ7lqLGn{1N0A&uQUucNc7N*o zIE>x}D+uY{AAzvE_hmZhRepDN>3q;X5){sE&wBp?_kn-@O-S;IxXWdJd}TiP*a#|( z;NGX}dD`tVKLnTgrFWJN1=7&cp;dWkLyCTD5)Se1iw=Gr6vv{VmnIkvg)LIug8fb3Juy YG4X9GDSRY++m{fgh0T0YIKx8mf3ntA=l}o! literal 0 HcmV?d00001 diff --git a/tests/migration/__pycache__/test_no_legacy_dependency.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_no_legacy_dependency.cpython-313-pytest-9.0.2.pyc index cf4def875ba25099b558068526eff9b8cf9b584e..a04404df87d76de7064b07dcbee27ab690e627ba 100644 GIT binary patch delta 72 zcmaFN_n(jJGcPX}0}zN_*~lf&svoVNn^&Trl30?cpPZjpl2{y{ms+l$n4X$f5)T!~ VPtJ@lNzE6}H#U%`4GQNi0d!Ps^+@GKw!V*&M;D&IAAyZVXNU diff --git a/tests/migration/__pycache__/test_observability_code_mapping.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_observability_code_mapping.cpython-313-pytest-9.0.2.pyc index cbec71399a370e585c3fa29a5dc236c52c8673fe..3d217c5d8910a7df7088f3245fc4a89f119faffd 100644 GIT binary patch delta 74 zcmeC%$+&7KBiCnMUM>b85WTXIYa+9LqJC~(iGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz5yT<_8e~s7)JF delta 46 zcmZ3rld*3nBiCnMUM>b8u#4HqHIZ4^RX;bcL_a05BvC&tv%<(IzRYCvDdqMy}7iyj%=GAbMpZ*LEiTBK_RF68)6Kl0^OF{JfIH;`qGOa{a{g)Vz{- Xs6c*lW_(F%Zb43BN$Tb+Oq{*|(8?P& delta 46 zcmex4pYiT|My}7iyj%=GU>CEIYde#0n0{_viGE6ANuqvQW`&Vae3{AS4@{iC09#28 A)Bpeg diff --git a/tests/migration/__pycache__/test_observability_mapping_provider_boundary.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_observability_mapping_provider_boundary.cpython-313-pytest-9.0.2.pyc index ed4eb4b7749d566857aff1727972ec52c0e84771..0bed412e200c4f2303821a65f5ac7017b47ee7e8 100644 GIT binary patch delta 72 zcmX@7^Gb*7GcPX}0}zN_*~m4ANk30NH?KrLC9xz?KRG|IB(XR?FST4hF+DY}Bpxb| VpPU(AlA2qPlUS0vc_-6UVE}$g8b|;D delta 44 ycmaE*b54irGcPX}0}$B7Y~-55Bpjrln^&Trl30?cpO#r+WE5X!viU00RAB%pxeew3 diff --git a/tests/migration/__pycache__/test_observability_mapping_registry_actions.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_observability_mapping_registry_actions.cpython-313-pytest-9.0.2.pyc index 6173e6c8db7a9470cc7fece40b0126060184cd41..9f882acb5244d3649538a05ef149528c6b2cbe67 100644 GIT binary patch delta 74 zcmZ3}!g!*Ek?S)rFBbz4h+f&qRl%d5tDl=!qMwpjlBl1YpI4Gt9G{n3uAi8mnpYAJ X706G{j4w&eEyzhMN!>h^XSyi>nW-A3 delta 46 zcmX@n!nme|k?S)rFBbz4*u`w*s^Ae0)X&W;(N9S%Nz_lvtS~Z)FEiP^k!QLo06QQK ALjV8( diff --git a/tests/migration/__pycache__/test_original_compliance_anatel.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_compliance_anatel.cpython-313-pytest-9.0.2.pyc index e08f1194377aee6ebd109562927de6e5693801c3..ae7a9a36a0af92230076ab425f0484f17b33632b 100644 GIT binary patch delta 74 zcmbQ!!MLM?k?S)rFBbz4h+f&qWy+(UsGplxqMwpjlBl1YpI4Gt9G{n3uAi8mnpYAJ X706G{j4w&eEyzhMN!=X8bIKe5fm|9e delta 46 zcmdnd!8oUbk?S)rFBbz4*u`w*GUX9=)z8f<(N9S%Nz_lvtS~Z)FEiPk$8*XY04^5| A&Hw-a diff --git a/tests/migration/__pycache__/test_original_contestation_validation.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_contestation_validation.cpython-313-pytest-9.0.2.pyc index 8a37edafde446f0e191ec4490eafd9e9c1fedff1..f3310dc1fe61888da0bae22c4afe9e06a0feaf74 100644 GIT binary patch delta 74 zcmZ3`&%CFfnd>tzFBbz4h+f&qrOBk9uAiG%qMwpjlBl1YpI4Gt9G{n3uAi8mnpYAJ X706G{j4w&eEyzhMN!{$m6m=8;go_$N delta 46 zcmdnf&%B_Ynd>tzFBbz4*u`w*(qt0$*3Zo=(N9S%Nz_lvtS~Z)FEiPk#1wTD05C2M A-~a#s diff --git a/tests/migration/__pycache__/test_original_item_matcher_transcription.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_item_matcher_transcription.cpython-313-pytest-9.0.2.pyc index 07b724c447209347c0560b3e2ff2ddfa09a41059..5bda56ca25681f342e90ce7d8d75b2804ee6acf0 100644 GIT binary patch delta 72 zcmcZ*^(KnzGcPX}0}zN_*~m3hR6k2UH?KrLC9xz?KRG|IB(XR?FST4hF+DY}Bpxb| VpPU(AlA2qPlUS0vd7J1gaR8fE8qELz delta 44 ycmaD8bs>uDGcPX}0}$B7Y~-3LD(t79n^&Trl30?cpO#r+WE5X!viXweEO7ui^$u$Q diff --git a/tests/migration/__pycache__/test_original_vas_cancellation_message.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_vas_cancellation_message.cpython-313-pytest-9.0.2.pyc index 7bbfe54f1c4605dbf7dab4366912248d5b758fc3..498c10f8890a8b297230a1f2bfcf1e0254fdb978 100644 GIT binary patch delta 74 zcmX@Pi}C3$My}7iyj%=GAbMpZ*FiS@4E@}^68)6Kl0^OF{JfIH;`qGOa{a{g)Vz{- Xs6c*lW_(F%Zb43BN$Tc%Y}sJ|)`ACEI>mZx3kA7}miGE6ANuqvQW`&Vae3{ASUu@Z70AC3Y AUjP6A diff --git a/tests/migration/__pycache__/test_original_vas_variation.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_vas_variation.cpython-313-pytest-9.0.2.pyc index f2a82911aa5cb791447ebb2039ceb433e6748fe9..e4098cb3373af4199b73ee9b41c9a1d955e3ff0b 100644 GIT binary patch delta 82 zcmdmbi{s)g4zACCEI>kX%{qke8)iGE6ANuqvQW`&Vae3?nJDp$KI7vpwS IE+!pi0N;5J)Bpeg diff --git a/tests/migration/__pycache__/test_original_vas_variation_adversarial.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_vas_variation_adversarial.cpython-313-pytest-9.0.2.pyc index 16d771bdedfbf79b9341f4b6194959729bef12d3..c6a6bcc60e71ce67d1b9da9670bdb4a5120a4bd1 100644 GIT binary patch delta 74 zcmZ2@iD~a8Ca%xCyj%=GAbMpZ*IY6EO#R%v68)6Kl0^OF{JfIH;`qGOa{a{g)Vz{- Xs6c*lW_(F%Zb43BN$TcZV(F6r$$J~L delta 46 zcmdmciD}^_Ca%xCyj%=GU>CEIYp$5EuYPV`iGE6ANuqvQW`&Vae3{ASYhvk>09RfQ AQUCw| diff --git a/tests/migration/__pycache__/test_original_workflow_cases.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_original_workflow_cases.cpython-313-pytest-9.0.2.pyc index fd43505f646e63460bf78f51f4d185c110a2d27d..1290e6227c8fcdb20453c95947ab6d70acf4fae6 100644 GIT binary patch delta 74 zcmZ2HiE;lVMy}7iyj%=GAbMpZR~xf_oPKUziGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz5y*<_1>)nsFMV delta 46 zcmdl#iE;5HMy}7iyj%=GU>CEItBqOMNk2EQL_a05BvC&tv%<(IzRYCve&z;O06XXo AK>z>% diff --git a/tests/migration/__pycache__/test_output_supervisor_no_contract_hardcodes.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_output_supervisor_no_contract_hardcodes.cpython-313-pytest-9.0.2.pyc index 3506cd2b23bef56420d2e657769c514f9a91e574..dae0dabcf784703d775a00d7f06267d766e22f37 100644 GIT binary patch delta 72 zcmaFw+wI5onU|M~0SH8|Y~*TT($CY+%`4GQNi0d!PtMOPNi2@fOD)$=Oi#@#iH8d0 VCuhc&q~;dnB$lLZUdZI90swjB8Rq~1 delta 44 ycmeD7d+*EjnU|M~0SN43HgdHv2?y!t=9TEDB$g!Vr)5?c8O4{GY~IV{rvd;aX$^${ diff --git a/tests/migration/__pycache__/test_pro_rata_full_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_pro_rata_full_parity.cpython-313-pytest-9.0.2.pyc index f2257f69c94b4061d4e4c13956a65c92a64b070c..c5a01b4d7d942afa57e5e3bb028e773c712497fd 100644 GIT binary patch delta 74 zcmZ26neoVEMy}7iyj%=GAbMpZR~D0gw0>@0iGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz1E;lcGBSmCza$ delta 46 zcmX>ynQ_HrMy}7iyj%=GU>CEID~n0kUOzXlL_a05BvC&tv%<(IzRYCvVkSj*06BLJ Avj6}9 diff --git a/tests/migration/__pycache__/test_rag_resilience_and_informational_context.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_rag_resilience_and_informational_context.cpython-313-pytest-9.0.2.pyc index ef9a5244a1e1f552811bde536ed195f134c2019a..545539dc2e0ba60fbbd9cb7f818758678be16c8e 100644 GIT binary patch delta 72 zcmeCsTcXGHnU|M~0SH8|Y~*5N)6dt>%`4GQNi0d!PtMOPNi2@fOD)$=Oi#@#iH8d0 VCuhc&q~;dnB$lLZR%UxD001|!80r83 delta 44 ycmZ3Y*P+MtnU|M~0SN43Hgd7C2?y)v=9TEDB$g!Vr)5?c8O4{GY_?~6DgXcg+zf~S diff --git a/tests/migration/__pycache__/test_real_legacy_integration_compat.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_real_legacy_integration_compat.cpython-313-pytest-9.0.2.pyc index 49e042e19e6bb52ce875d2c82015d7a05bb7b7e8..5566fb011e112ab961ef1666a8629cad492a6dfc 100644 GIT binary patch delta 72 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 diff --git a/tests/migration/__pycache__/test_revprec_epistemic_uncertainty.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_revprec_epistemic_uncertainty.cpython-313-pytest-9.0.2.pyc index a9c5d9130a201efc09ce34e3013c123f2c279d5b..afaf712a8b9a2121f6460edb4d1ab847cc5a43c1 100644 GIT binary patch delta 72 zcmdn&aNdFIGcPX}0}zN_*~s;VQ9ngLH?KrLC9xz?KRG|IB(XR?FST4hF+DY}Bpxb| VpPU(AlA2qPlUS0vnUhIN4giIx8E*gp delta 44 ycmX@_u-Sp@GcPX}0}$B7Y~*^wDD0u1n^&Trl30?cpO#r+WE5X!vRRc$OAY`k5)BOi diff --git a/tests/migration/__pycache__/test_subject_entity_resolution_all_domains.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_subject_entity_resolution_all_domains.cpython-313-pytest-9.0.2.pyc index 495e054ab206ceb5cb548dc2bf906cc192f61ee2..52bc7629b96b86841ed00dd60de1e87c5726668b 100644 GIT binary patch delta 2909 zcmb`Je{5S<702JTpMU3<^ZQ4WJm*JSC#jue4vlF^SGLAuZPO;NDOIKJ_1S(&9c;h! zzUMRznv!h@hBP#_mk2Qxt@~qW6B}DGlmbI^z~G;0vXe})tVwi&KL(ma(iAbaAvovR zb&52837+2j_}qKH_uT7q?>qN>`7QF^9a6DXUhd@J+W-9W%(dN@DjLb!wO!vJRHHx=K>E&TJ6UEQ zk5Zr-3X@mTE1@$Ea-H>$_wD!*N`H*_3F0+?*F>+NeVxsZKL!0Q69V~=?VM;MKV^p| zPD9PriI>Qm>7(NB91oTHd(C-Xzc{NC0zcBjlO%G3g~j-ew=49jSUA8=DY1;@j+D`7bq@MCmRAr@Aij$&hkKe?O*l&4P0xp)GYv(cu5>xT!XR(` z!NhUPoJd5IXa@2=lV~aY`c0zM$1c@-T9QPxsh$q*lrRKpypm>-Qy-Y*kFfE>gAV(o zB|t>SsQ}yQ4zf26&#^b$9ZYR=un(F%?6}Ke5?$=M(*kREx!Kdl!o+pC#>39u?_{mV zd&u@AzjgQDUpinF$uSdq|7Uk zlpa%)()J)xRnerRs!LR%il)Zr6lq3{C6(yi;puO|;~(MC-UBRgx2oH7HU3+5-LJN0 z%MRq~JTIKdmhIcHn5&(eHd~o>>A^cyTv^q+Yq2Bi>d5e+Oy@8X?9Sm;*8#9^1`2S6 z*7@SSii!iJV!?Qu4?Ptq)n&I!&;b4lE!eYjxTGo=YkcU&>8?^GbiGk58C{D5LD!qx z{!3~wV1CpOe>Xw^cP~2_Pr$R)#l|MT#v1ljvA<2a*gGBdOgL$=_j96CbongoqmEWb znFWNfAIq7ibI4Xm5m*FfvU-Asqhj>F%7n3M4eNp9F8l}g_wR$iY4dN zSVSpGeEZ{SM2>4CzN9KCNg9is`zu78egP3jBoLPYkz#fLljCqbYsvsyn5&k#X$~f| zV-b^iUi?4KYJVIuL{uIjFrbD*Epaz>V@u^*=Hz$`4kN`ldW--p;yY<%^M9BuE@2Hk zTlIitZt`wI*!(temBa zWqVqW3}yp|*Z3njzH*&!$np(W_)OcrP0l`Iy~Eipwma2aZR2{4Z>7eU!-U?Mb2sL8 zwB;IlH(l0#>lSCNwf&j1R@jzCH!7IW`|_gq>aGkA$hy4ieDPl4y%|?qp}2OBy^6w; zs$@WQ&gITj!@wNKE;e8obXQ8-ukG;w-g1jUv8LPZ6=c>!_fsAlp zwh4}vK&B~>bwN@u-Yb0I$xjzbYuo0kp(}|>2GsvEcb_ka{yTp#z&H_H%xtG@9js3gFHkw8ab2wD=m+;tdrU-sogZSkfALzXR0$S H!`t5h30qQ~ delta 458 zcmX}m-7AAp90zc}$EXcUDQ_9ejh><>qLErD*>WL!tX8t-SzcG9<7qu}qov$T$lKXi+xZ4t97U@gud!A;(GjF=|MZ zBkIW_W*u@&O!iSgbfMy}7iyj%=GAbMpZ*E(kXZ2jE468)6Kl0^OF{JfIH;`qGOa{a{g)Vz{- Xs6c*lW_(F%Zb43BN$Td)%;l~Cx5^te delta 46 zcmcaNiSf`RMy}7iyj%=GU>CEIYaO$&zkY6BiGE6ANuqvQW`&Vae3{AS=gj4<08Fh8 A(*OVf diff --git a/tests/migration/__pycache__/test_tim_contract_parity.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_tim_contract_parity.cpython-313-pytest-9.0.2.pyc index 11e034fb07b103a6c32e601db3abf74f2b5a713f..8850bd133711c2c9835feb284ba48dcb7d3d503e 100644 GIT binary patch delta 72 zcmZojoRi4)nU|M~0SH8|Y~*U^)sNE8%`4GQNi0d!PtMOPNi2@fOD)$=Oi#@#iH8d0 VCuhc&q~;dnB$lLZUc!4v2>@y<8bkm9 delta 44 ycmbP}*pSHenU|M~0SN43HgdJ|3ft-D=9TEDB$g!Vr)5?c8O4{GY(BtyM+pEOS`Fd= diff --git a/tests/migration/__pycache__/test_tim_contracts_and_idempotency.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_tim_contracts_and_idempotency.cpython-313-pytest-9.0.2.pyc index cfddac43af17fa9134a87f64d81c086324846313..63c35f1139bd9e3fadc0b0ac076a72437dee3375 100644 GIT binary patch delta 72 zcmdm6e6yJAGcPX}0}zN_*~k^Zq@SXnn^&Trl30?cpPZjpl2{y{ms+l$n4X$f5)T!~ VPtJ@lNzE+f$9DPCa%xCyj%=GAbMpZ7cY~3f_`pZiGE6ANuqvoeqKppaeQ8Cxqf1LYFw;(66Bz3bElVlqJkG~no delta 46 zcmcaVf$8uBCa%xCyj%=GU>CEIi_eF8dLxP delta 44 ycmaE#eL0)!GcPX}0}$B7Y~-5AC~T{rn^&Trl30?cpO#r+WE5X!viTIFstEu(>J9P$ diff --git a/tests/migration/__pycache__/test_vas_response_renderer.cpython-313-pytest-9.0.2.pyc b/tests/migration/__pycache__/test_vas_response_renderer.cpython-313-pytest-9.0.2.pyc index c6252bef6c546d7653ff60104d4191c8690f08b2..8cf0c5111f03542cedac488c5a68c93d91a311bf 100644 GIT binary patch delta 72 zcmdn2bY6+;GcPX}0}zN_*~lf%sUM@Cn^&Trl30?cpPZjpl2{y{ms+l$n4X$f5)T!~ VPtJ@lNzE6n4nU|M~0SK}#Z{!MO6n56n%`4GQNi0d!Ps^+@GKw!V+1$lASq1