diff --git a/gitgalaxy/standards/language_standards/_shared_patterns.py b/gitgalaxy/standards/language_standards/_shared_patterns.py index 7b232b694..5bcb63a50 100644 --- a/gitgalaxy/standards/language_standards/_shared_patterns.py +++ b/gitgalaxy/standards/language_standards/_shared_patterns.py @@ -43,7 +43,26 @@ r"للقيام به|لاحقا|يجب عمله" # Arabic r")" ) -GLOBAL_PLANNED_DEBT = re.compile(f"{_SPACED_PLANNED}|{_DENSE_PLANNED}", re.I) +# #2537: `-` is a regex word boundary, so the bare `\b(...)\b` alternations +# matched debt keywords EMBEDDED INSIDE hyphenated code identifiers -- COBOL +# data items (`HACK-LEVEL`, `BUG-COUNT`), COBOL/Lisp-family paragraph and +# symbol names (`PROBE-TODO`, `probe-todo`), css classes (`.bug-icon`) -- +# inflating tech-debt scoring from ordinary code in exactly the hyphenated- +# identifier ecosystems (COBOL/JCL, Lisp, css) where debt measurement matters +# most. Python's `HACK_LEVEL` was inert only by tokenization luck (`_` is a +# word char, so `\bHACK\b` can't fire mid-identifier). +# THE GUARD: refuse a match glued to a hyphen-plus-alphanumeric on either +# side -- the shape of an identifier CONTINUING through the hyphen. Real +# comment markers keep counting, including hyphen-adjacent ones whose +# neighbor char is NOT alphanumeric: `-- TODO x` (Ada/Haskell/SQL comments), +# a glued `--TODO`, or a trailing `TODO--` (the char beside the hyphen is +# another `-`, not a letter/digit). Deliberately scoped to the SPACED +# (Latin/Cyrillic) alternation only: the DENSE CJK/RTL alternation has no +# hyphenated-identifier idiom to guard against. +_HYPHEN_IDENT_PRE = r"(? (make-point x y) point?)") assert SCHEME_RULES["globals"].search("(define default->value 5)") + _SCHEME_DEEP_CASES = [ # branch ("branch", "(\n if a b c)", "xif"), @@ -331,27 +332,23 @@ def test_scheme_redos_immunity_sweep(): ("branch", "(cond\n (else 1))", "conditional"), ("branch", "(when (and a b))", "awhen"), ("branch", "unless", "runless"), - # args ("args", "(define (foo \n x \n y)\n ...)", "(define foo 5)"), ("args", "(define (foo))", "(define (foo"), ("args", "(define (foo . rest) ...)", "(define foo (lambda (x) x))"), ("args", "(define (foo!x y))", "(define foo!x)"), ("args", "(define (a-b-c d e))", "(+ 1 2)"), - # func_start ("func_start", "(define (call/cc-wrapper x) ...)", "(define foo 5)"), ("func_start", "(\n define (foo x))", "(define-syntax foo)"), ("func_start", "(define (* a b) ...)", None), ("func_start", "(define (1+ x) x)", "(define)"), - ("func_start", "(define (foo))", "define (foo)"), # space instead of ( - + ("func_start", "(define (foo))", "define (foo)"), # space instead of ( # class_start ("class_start", "(define-record-type point)", "(define-record-type)"), ("class_start", "(\n define-record-type )", "(define (define-record-type x))"), ("class_start", "(define-record-type (point x y))", "(+ 1 2)"), ("class_start", "(define-record-type point\n (make-point))", "define-record-type x"), - # structural_boundaries ("structural_boundaries", "(let ((x 1)) x)", "let-syntax"), ("structural_boundaries", "(let* ((x 1)) x)", "foo-let"), @@ -360,6 +357,7 @@ def test_scheme_redos_immunity_sweep(): ("structural_boundaries", "(do ((i 0 (+ i 1))) ((= i 5)) i)", "redo"), ] + @pytest.mark.parametrize("signature,positive,negative", _SCHEME_DEEP_CASES) def test_scheme_deep_cases(signature, positive, negative): pattern = SCHEME_RULES[signature] @@ -367,3 +365,20 @@ def test_scheme_deep_cases(signature, positive, negative): assert pattern.search(positive), f"Deep positive failed for {signature}: {positive!r}" if negative: assert not pattern.search(negative), f"Deep negative failed for {signature}: {negative!r}" + + +def test_scheme_debt_rules_ignore_hyphenated_symbols_regression(): + """#2537: scheme reproduces the hyphenated-identifier debt leak -- a + `(define (probe-todo ...))` symbol recorded planned_debt alongside the + real `;; TODO:` comment (the #1096 control corpus measured planned_debt + 2 for one planted marker). Kebab-case is THE Lisp-family naming + convention, so ordinary symbols must never feed debt scoring.""" + planned = SCHEME_RULES["planned_debt"] + fragile = SCHEME_RULES["fragile_debt"] + + corpus_shaped = "(define (probe-todo plan)\n ;; TODO: fill in the probe body later\n 'planned)\n" + assert len(planned.findall(corpus_shaped)) == 1, "planned_debt must count ONLY the ;; TODO: comment" + + for text in ("(fix-me-later x)", "(define bug-tracker '())", "(hack-level 9)"): + assert not fragile.search(text), f"fragile_debt matched inside symbol: {text!r}" + assert not planned.search(text), f"planned_debt matched inside symbol: {text!r}" diff --git a/tests/golden_master_audit.json b/tests/golden_master_audit.json index 7053962f7..ef1020eea 100644 --- a/tests/golden_master_audit.json +++ b/tests/golden_master_audit.json @@ -11,14 +11,14 @@ "pyyaml": false }, "Target Root Name": "data", - "Absolute Project Path": "/home/joe/nyx_projects/language-crucible/data", - "Analysis ISO Timestamp": "2026-08-31T20:55:44.403298+00:00", - "Total Scan Duration": "54.93 seconds" + "Absolute Project Path": "/srv/storage_16tb/projects/gitgalaxy/language-crucible/data", + "Analysis ISO Timestamp": "2026-08-31T22:52:15.971169+00:00", + "Total Scan Duration": "20.47 seconds" }, "Source Control Footprint (Immutable Anchor)": { "Active Branch": "HEAD", "Commit Hash (SHA-1)": "77bc85ecb8bb2fa8331b83f2bd348ec735df66e3", - "Remote Origin URL": "https://github.com/squid-protocol/language-crucible", + "Remote Origin URL": "https://github.com/squid-protocol/language-crucible.git", "Last Code Integration Date": "2026-08-30T08:52:00-04:00" } }, @@ -238,7 +238,7 @@ "health": { "avg_cognitive_load": 29.79, "avg_safety_score": 47.68, - "avg_tech_debt": 32.24, + "avg_tech_debt": 32.218, "avg_documentation": 28.806 }, "composition": { @@ -3284,7 +3284,7 @@ "avg_exposures": { "cognitive_load": 2.61, "safety_score": 0.0, - "tech_debt": 13.66, + "tech_debt": 12.64, "verification": 1.15, "api_exposure": 5.51, "concurrency": 0.0, @@ -3531,7 +3531,7 @@ "avg_exposures": { "cognitive_load": 35.61, "safety_score": 37.33, - "tech_debt": 14.96, + "tech_debt": 12.57, "verification": 12.63, "api_exposure": 2.18, "concurrency": 0.0, @@ -3911,7 +3911,7 @@ "avg_exposures": { "cognitive_load": 36.28, "safety_score": 37.92, - "tech_debt": 31.78, + "tech_debt": 31.4, "verification": 30.55, "api_exposure": 1.17, "concurrency": 0.0, @@ -4405,7 +4405,7 @@ "avg_exposures": { "cognitive_load": 19.67, "safety_score": 10.54, - "tech_debt": 35.01, + "tech_debt": 34.81, "verification": 35.7, "api_exposure": 0.51, "concurrency": 11.33, @@ -198687,7 +198687,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "19.67%", "Error & Exception Exposure": "10.54%", - "Tech Debt Exposure": "35.01%", + "Tech Debt Exposure": "34.81%", "Testing Exposure": "35.7%", "API Exposure": "0.51%", "Concurrency Exposure": "11.33%", @@ -209340,7 +209340,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "15.85%", "Error & Exception Exposure": "16.07%", - "Tech Debt Exposure": "43.64%", + "Tech Debt Exposure": "42.23%", "Testing Exposure": "2.47%", "API Exposure": "0.13%", "Concurrency Exposure": "0.0%", @@ -212372,7 +212372,7 @@ "Module Dependencies (Imports)": 13, "Authorship Metadata": 0, "Planned Work (TODOs)": 16, - "Acknowledged Tech Debt (FIXMEs)": 1, + "Acknowledged Tech Debt (FIXMEs)": 0, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0, @@ -294894,7 +294894,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "36.28%", "Error & Exception Exposure": "37.92%", - "Tech Debt Exposure": "31.78%", + "Tech Debt Exposure": "31.4%", "Testing Exposure": "30.55%", "API Exposure": "1.17%", "Concurrency Exposure": "0.0%", @@ -297609,7 +297609,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "94.5%", "Error & Exception Exposure": "89.82%", - "Tech Debt Exposure": "88.35%", + "Tech Debt Exposure": "61.61%", "Testing Exposure": "80.0%", "API Exposure": "1.66%", "Concurrency Exposure": "0.0%", @@ -298661,7 +298661,7 @@ "Module Dependencies (Imports)": 56, "Authorship Metadata": 0, "Planned Work (TODOs)": 0, - "Acknowledged Tech Debt (FIXMEs)": 1, + "Acknowledged Tech Debt (FIXMEs)": 0, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0, @@ -716424,7 +716424,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "35.61%", "Error & Exception Exposure": "37.33%", - "Tech Debt Exposure": "14.96%", + "Tech Debt Exposure": "12.57%", "Testing Exposure": "12.63%", "API Exposure": "2.18%", "Concurrency Exposure": "0.0%", @@ -717359,7 +717359,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "100.0%", "Error & Exception Exposure": "26.81%", - "Tech Debt Exposure": "45.69%", + "Tech Debt Exposure": "12.19%", "Testing Exposure": "80.0%", "API Exposure": "0.14%", "Concurrency Exposure": "0.0%", @@ -717451,7 +717451,7 @@ "Module Dependencies (Imports)": 2, "Authorship Metadata": 0, "Planned Work (TODOs)": 1, - "Acknowledged Tech Debt (FIXMEs)": 4, + "Acknowledged Tech Debt (FIXMEs)": 0, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0, @@ -867552,7 +867552,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "2.61%", "Error & Exception Exposure": "0.0%", - "Tech Debt Exposure": "13.66%", + "Tech Debt Exposure": "12.64%", "Testing Exposure": "1.15%", "API Exposure": "5.51%", "Concurrency Exposure": "0.0%", @@ -867760,7 +867760,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "5.21%", "Error & Exception Exposure": "0.0%", - "Tech Debt Exposure": "27.32%", + "Tech Debt Exposure": "25.29%", "Testing Exposure": "2.3%", "API Exposure": "11.01%", "Concurrency Exposure": "0.0%", @@ -867822,7 +867822,7 @@ "Module Dependencies (Imports)": 0, "Authorship Metadata": 1, "Planned Work (TODOs)": 1, - "Acknowledged Tech Debt (FIXMEs)": 12, + "Acknowledged Tech Debt (FIXMEs)": 11, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0, diff --git a/tests/golden_master_zero_dep_audit.json b/tests/golden_master_zero_dep_audit.json index a5214e3df..9983c449a 100644 --- a/tests/golden_master_zero_dep_audit.json +++ b/tests/golden_master_zero_dep_audit.json @@ -11,14 +11,14 @@ "pyyaml": false }, "Target Root Name": "data", - "Absolute Project Path": "/home/joe/nyx_projects/language-crucible/data", - "Analysis ISO Timestamp": "2026-08-31T20:57:30.709225+00:00", - "Total Scan Duration": "49.87 seconds" + "Absolute Project Path": "/srv/storage_16tb/projects/gitgalaxy/language-crucible/data", + "Analysis ISO Timestamp": "2026-08-31T22:52:40.726425+00:00", + "Total Scan Duration": "18.44 seconds" }, "Source Control Footprint (Immutable Anchor)": { "Active Branch": "HEAD", "Commit Hash (SHA-1)": "77bc85ecb8bb2fa8331b83f2bd348ec735df66e3", - "Remote Origin URL": "https://github.com/squid-protocol/language-crucible", + "Remote Origin URL": "https://github.com/squid-protocol/language-crucible.git", "Last Code Integration Date": "2026-08-30T08:52:00-04:00" } }, @@ -238,7 +238,7 @@ "health": { "avg_cognitive_load": 29.79, "avg_safety_score": 47.68, - "avg_tech_debt": 32.24, + "avg_tech_debt": 32.218, "avg_documentation": 28.806 }, "composition": { @@ -3284,7 +3284,7 @@ "avg_exposures": { "cognitive_load": 2.61, "safety_score": 0.0, - "tech_debt": 13.66, + "tech_debt": 12.64, "verification": 1.15, "api_exposure": 5.51, "concurrency": 0.0, @@ -3531,7 +3531,7 @@ "avg_exposures": { "cognitive_load": 35.61, "safety_score": 37.33, - "tech_debt": 14.96, + "tech_debt": 12.57, "verification": 12.63, "api_exposure": 2.18, "concurrency": 0.0, @@ -3911,7 +3911,7 @@ "avg_exposures": { "cognitive_load": 36.28, "safety_score": 37.92, - "tech_debt": 31.78, + "tech_debt": 31.4, "verification": 30.55, "api_exposure": 1.17, "concurrency": 0.0, @@ -4405,7 +4405,7 @@ "avg_exposures": { "cognitive_load": 19.67, "safety_score": 10.54, - "tech_debt": 35.01, + "tech_debt": 34.81, "verification": 35.7, "api_exposure": 0.51, "concurrency": 11.33, @@ -198687,7 +198687,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "19.67%", "Error & Exception Exposure": "10.54%", - "Tech Debt Exposure": "35.01%", + "Tech Debt Exposure": "34.81%", "Testing Exposure": "35.7%", "API Exposure": "0.51%", "Concurrency Exposure": "11.33%", @@ -209340,7 +209340,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "15.85%", "Error & Exception Exposure": "16.07%", - "Tech Debt Exposure": "43.64%", + "Tech Debt Exposure": "42.23%", "Testing Exposure": "2.47%", "API Exposure": "0.13%", "Concurrency Exposure": "0.0%", @@ -212372,7 +212372,7 @@ "Module Dependencies (Imports)": 13, "Authorship Metadata": 0, "Planned Work (TODOs)": 16, - "Acknowledged Tech Debt (FIXMEs)": 1, + "Acknowledged Tech Debt (FIXMEs)": 0, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0, @@ -294894,7 +294894,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "36.28%", "Error & Exception Exposure": "37.92%", - "Tech Debt Exposure": "31.78%", + "Tech Debt Exposure": "31.4%", "Testing Exposure": "30.55%", "API Exposure": "1.17%", "Concurrency Exposure": "0.0%", @@ -297609,7 +297609,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "94.5%", "Error & Exception Exposure": "89.82%", - "Tech Debt Exposure": "88.35%", + "Tech Debt Exposure": "61.61%", "Testing Exposure": "80.0%", "API Exposure": "1.66%", "Concurrency Exposure": "0.0%", @@ -298661,7 +298661,7 @@ "Module Dependencies (Imports)": 56, "Authorship Metadata": 0, "Planned Work (TODOs)": 0, - "Acknowledged Tech Debt (FIXMEs)": 1, + "Acknowledged Tech Debt (FIXMEs)": 0, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0, @@ -716424,7 +716424,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "35.61%", "Error & Exception Exposure": "37.33%", - "Tech Debt Exposure": "14.96%", + "Tech Debt Exposure": "12.57%", "Testing Exposure": "12.63%", "API Exposure": "2.18%", "Concurrency Exposure": "0.0%", @@ -717359,7 +717359,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "100.0%", "Error & Exception Exposure": "26.81%", - "Tech Debt Exposure": "45.69%", + "Tech Debt Exposure": "12.19%", "Testing Exposure": "80.0%", "API Exposure": "0.14%", "Concurrency Exposure": "0.0%", @@ -717451,7 +717451,7 @@ "Module Dependencies (Imports)": 2, "Authorship Metadata": 0, "Planned Work (TODOs)": 1, - "Acknowledged Tech Debt (FIXMEs)": 4, + "Acknowledged Tech Debt (FIXMEs)": 0, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0, @@ -867552,7 +867552,7 @@ "Average Risk Exposures": { "Cognitive Load Exposure": "2.61%", "Error & Exception Exposure": "0.0%", - "Tech Debt Exposure": "13.66%", + "Tech Debt Exposure": "12.64%", "Testing Exposure": "1.15%", "API Exposure": "5.51%", "Concurrency Exposure": "0.0%", @@ -867760,7 +867760,7 @@ "4. Vulnerability & Risk Exposures": { "Cognitive Load Exposure": "5.21%", "Error & Exception Exposure": "0.0%", - "Tech Debt Exposure": "27.32%", + "Tech Debt Exposure": "25.29%", "Testing Exposure": "2.3%", "API Exposure": "11.01%", "Concurrency Exposure": "0.0%", @@ -867822,7 +867822,7 @@ "Module Dependencies (Imports)": 0, "Authorship Metadata": 1, "Planned Work (TODOs)": 1, - "Acknowledged Tech Debt (FIXMEs)": 12, + "Acknowledged Tech Debt (FIXMEs)": 11, "Specification Traceability Tags": 0, "Server-Side Rendering Contexts": 0, "Event Publishers / Emitters": 0,