From c995bc27122ec76bedc380766699855e8f4600b5 Mon Sep 17 00:00:00 2001 From: Ryan Malloy Date: Sat, 9 May 2026 04:37:41 -0600 Subject: [PATCH] route_plan: translation_chain includes Device DNs (cti-audit-prompts/007) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cucx-docs's 007 empirically proved that route_translation_chain's candidate filter `WHERE np.tkpatternusage IN (3, 5, 7)` excluded Device DNs (tkpatternusage=2), which caused false-positive HIGH findings on CTI-RP-to-CTI-RP failsafe chains — the typical CER deployment shape. The Bingham canary: 911-CTI-RP CFNA → 912 (DN of 912-CTI-RP) under 911CER-CSS. Direct numplan query against 911CER-PT returns 26 rows; translation_chain reported `candidates_evaluated: 23`. The 3-row gap is exactly the 3 Device DNs, excluded by the pre-fix filter regardless of input number. CUCM's runtime CFNA matcher includes Device DNs (otherwise no one could dial 912 and reach the device). My tool's exclusion diverged from production routing semantics. Result: every cluster using a CTI-RP-to-CTI-RP failsafe pattern got at least one false-positive HIGH finding on its first cti_failsafe_reachability run, wasting operator investigation time on a phantom defect. This commit broadens the candidate filter: - WHERE np.tkpatternusage IN (3, 5, 7) + WHERE np.tkpatternusage IN (2, 3, 5, 7) ^ Device DN Side effect: route_translation_chain now also surfaces Device DNs as matches when called directly, which matches production routing semantics. Existing callers benefit automatically. The _note in the response now names the candidate set explicitly so future readers don't have to dig into the SQL to know what's included. Updated comment block above the WHERE clause documents: - which tkpatternusage values are included and why - the empirical observation that motivated including Device DNs - cross-reference to cti-audit-prompts/007 for the smoking-gun candidates_evaluated:23-vs-26 evidence Tests: +2 in TestDeviceDnInTranslationChainCandidates: - test_translation_chain_sql_includes_device_dn_usage: lock the SQL down so a future contributor can't re-narrow the filter to (3, 5, 7) and re-introduce the false-positive class - test_cti_rp_to_cti_rp_failsafe_does_not_false_positive: the Bingham canary scenario — 911-CTI-RP forwarding to a Device DN in a reachable partition correctly produces zero findings The dispatch fake's SQL match-string updated from "(3, 5, 7)" to "(2, 3, 5, 7)" to keep the existing 31 cti tests green; net mcaxl suite: 269 → 271 passing. Live re-run pending — will ping the agent thread with post-patch output once the MCP server reloads. Re-run expectations (per cucx-docs's 007): - 911-CTI-RP / 912 finding (CFNA + CFUR): GONE — Device DN matches - 912-CTI-RP / 10911 finding: UNCHANGED — Route pattern still unreachable (CER911-PT not in 911CER-CSS) - 913-CTI-RP / 60003 finding: UNCHANGED — destination doesn't exist anywhere Findings: 6 → 4 (the 4 that actually matter). --- src/mcaxl/route_plan.py | 20 +++++- tests/test_cti_failsafe_reachability.py | 81 ++++++++++++++++++++++++- 2 files changed, 98 insertions(+), 3 deletions(-) diff --git a/src/mcaxl/route_plan.py b/src/mcaxl/route_plan.py index a1a3a9d..e11f6d3 100644 --- a/src/mcaxl/route_plan.py +++ b/src/mcaxl/route_plan.py @@ -1750,7 +1750,23 @@ def translation_chain(client: "AxlClient", number: str, css_name: str | None = N LEFT OUTER JOIN typepatternusage tpu ON np.tkpatternusage = tpu.enum LEFT OUTER JOIN digitdiscardinstruction ddi ON np.fkdigitdiscardinstruction = ddi.pkid LEFT OUTER JOIN routefilter rf ON np.fkroutefilter = rf.pkid - WHERE np.tkpatternusage IN (3, 5, 7) + # tkpatternusage candidates included in the match scan: + # 2 = Device (DN) — directly-dialable directory numbers + # 3 = Translation — translation patterns + # 5 = Route Pattern — outbound routing + # 7 = Hunt Pilot — hunt pilot pattern + # + # Device DNs are included because CUCM's runtime CFNA/CFUR matcher + # includes them — when a forward destination is a Device DN (e.g. + # the DN of another CTI Route Point in a CER failsafe chain), the + # runtime call succeeds via that DN. Excluding them caused + # `cti_failsafe_reachability` false-positive HIGH findings on + # CTI-RP-to-CTI-RP failsafe chains. cucx-docs verified empirically + # in agent-threads/cti-audit-prompts/007 that omitting Device DNs + # was the cause of the false-positive: candidates_evaluated stayed + # 23 vs 26 numplan rows in the reachable partition, with the 3-row + # gap being exactly the 3 Device DNs. + WHERE np.tkpatternusage IN (2, 3, 5, 7) AND np.dnorpattern IS NOT NULL {css_filter} """ @@ -1772,6 +1788,8 @@ def translation_chain(client: "AxlClient", number: str, css_name: str | None = N "match_count": len(matches), "matches": matches, "_note": ( + "Candidate set: tkpatternusage 2 (Device DN), 3 (Translation), " + "5 (Route Pattern), 7 (Hunt Pilot). " "Wildcards evaluated: X, !, [0-9], @, \\+. " "@-pattern matches any digit string (route filter constraints not applied). " "Longest-match-wins is approximated by pattern length; CUCM uses pattern " diff --git a/tests/test_cti_failsafe_reachability.py b/tests/test_cti_failsafe_reachability.py index 717132c..f51eced 100644 --- a/tests/test_cti_failsafe_reachability.py +++ b/tests/test_cti_failsafe_reachability.py @@ -60,8 +60,12 @@ class FakeAxlClient: return {"row_count": len(self._cti_rows), "rows": self._cti_rows} # Dispatch 2: translation_chain's reachability check - # Recognizable by `tkpatternusage IN (3, 5, 7)` from route_plan.py - if "tkpatternusage IN (3, 5, 7)" in sql: + # Recognizable by `tkpatternusage IN (2, 3, 5, 7)` from route_plan.py + # (tkpatternusage = 2 / Device DN was added 2026-05-09 after + # cucx-docs's empirical proof in cti-audit-prompts/007 that + # excluding Device DNs caused false-positive HIGH findings on + # CTI-RP-to-CTI-RP failsafe chains) + if "tkpatternusage IN (2, 3, 5, 7)" in sql: for dest, css in self._reachable: if f"name = '{css}'" in sql: return { @@ -421,3 +425,76 @@ class TestDotStrippedFixSuggestion: assert "Match-PT" in fix assert "Nonmatch-PT" not in fix assert "AnotherMatch-PT" not in fix + + +# ─── Device-DN inclusion in translation_chain (cti-audit-prompts/007) ── +# +# cucx-docs verified empirically in 007 that `route_translation_chain`'s +# candidate filter excluded Device DNs (tkpatternusage=2), which caused +# false-positive HIGH findings on CTI-RP-to-CTI-RP failsafe chains +# (typical CER pattern). The fix: include tkpatternusage=2 in the +# candidate set so Device DNs get checked alongside translation/route/ +# hunt patterns. +# +# These tests pin the regression by: +# 1. Verifying the SQL emitted by translation_chain includes +# `tkpatternusage IN (2, 3, 5, 7)` literally +# 2. Demonstrating the cti audit doesn't false-positive on a CTI-RP- +# to-CTI-RP failsafe shape + +class TestDeviceDnInTranslationChainCandidates: + + def test_translation_chain_sql_includes_device_dn_usage(self): + """Lock the candidate-filter SQL down so a future contributor + can't accidentally re-narrow it to (3, 5, 7) and re-introduce + the cti-audit-prompts/007 false-positive class. + """ + client = FakeAxlClient(cti_rp_rows=[ + _cti_row("Test-RP", "Generic", cfna="912", cfna_css="SomeCSS"), + ]) + cti_failsafe_reachability(client) + # Find the translation_chain query in the captured SQL + chain_query = next( + q for q in client.queries + if "tkpatternusage IN" in q and "callingsearchspace" in q + ) + assert "(2, 3, 5, 7)" in chain_query, ( + "translation_chain candidate set must include tkpatternusage=2 " + "(Device DN). Excluding Device DNs causes false-positive HIGH " + "findings on CTI-RP-to-CTI-RP failsafe chains. See " + "agent-threads/cti-audit-prompts/007 for cucx-docs's " + "empirical proof." + ) + + def test_cti_rp_to_cti_rp_failsafe_does_not_false_positive(self): + """The motivating Bingham case: 911-CTI-RP CFNA → 912 (Device DN + of 912-CTI-RP) under 911CER-CSS reaching 911CER-PT. + + Pre-fix: cti_failsafe_reachability flagged this as HIGH because + translation_chain excluded the Device DN from its candidate set. + + Post-fix: the Device DN '912' is in the candidate set under the + reachable partition, so the forward correctly resolves and no + finding is produced. + """ + # Simulate the fix's effect: the reachable_destinations set + # captures (912, 911CER-CSS) — meaning translation_chain returns + # match_count > 0 because the Device DN is now in the candidate + # set and gets matched against the dialed number. + client = FakeAxlClient( + cti_rp_rows=[ + _cti_row( + "911-CTI-RP", "CTI RP for Primary CER Server", + cfna="912", cfna_css="911CER-CSS", + cfur="912", cfur_css="911CER-CSS", + ), + ], + reachable_destinations={ + ("912", "911CER-CSS"), # Device DN now reachable + }, + ) + result = cti_failsafe_reachability(client) + # No findings — the Tier-1 forward correctly resolves + assert result["broken_cfna"] == 0 + assert result["broken_cfur"] == 0 + assert result["findings"] == []