Add Cadence code-pattern parity signal

ober

59c43d41abab663d0b16e87f0fbaa7190e336390

diff --git a/GAPS.md b/GAPS.md
index f99cff7..2b90d6d 100644
--- a/GAPS.md
+++ b/GAPS.md
@@ -219,6 +219,10 @@ Acceptance criteria:
 Cadence detects generic variables/functions, overly regular camelCase, dense
   error-handling scaffolding, template patterns, and TODO/FIXME patterns.
 
+Status: implemented as `cadence-code-patterns` for generic scaffold names,
+regular generated-style names, dense error-handling terms, large scaffold-like
+blocks, and TODO/FIXME/debug counter-evidence.
+
 Acceptance criteria:
 
 - Add separate evidence items for generic names, naming-style regularity, dense
diff --git a/main-binary.ss b/main-binary.ss
index 93a2eba..85ff132 100644
--- a/main-binary.ss
+++ b/main-binary.ss
@@ -456,6 +456,36 @@
                            phrases)])
     (sig "lexical-code-style" "code" score 0.35 "medium" "added code has lexical/comment patterns associated with generated scaffolding" evidence
          "language-neutral lexical analysis is noisy")))
+(def error-handling-terms '("try" "catch" "except" "raise" "throw" "throws" "error" "errors" "exception" "fallback" "retry"))
+(def scaffold-name-fragments '("helper" "handler" "manager" "processor" "service" "client" "controller" "factory" "adapter"))
+(def (contains-any-fragment? text fragments)
+  (for/or ([fragment fragments]) (contains? text fragment)))
+(def (regular-generated-name? lexeme)
+  (and (contains-any-fragment? lexeme scaffold-name-fragments)
+       (for/or ([ch (in-string lexeme)]) (char-numeric? ch))))
+(def (cadence-code-pattern-signal lines)
+  (let* ([nonblank (filter (lambda (line) (not (blank? line))) lines)]
+         [text (down (string-join nonblank "\n"))]
+         [lexemes (source-lexemes nonblank)]
+         [generic-family-count (count-where (lambda (lexeme) (contains-any-fragment? lexeme scaffold-name-fragments)) lexemes)]
+         [generic-family-ratio (if (null? lexemes) 0.0 (/ (exact->inexact generic-family-count) (length lexemes)))]
+         [regular-name-count (count-where regular-generated-name? lexemes)]
+         [error-count (count-where (lambda (lexeme) (member lexeme error-handling-terms)) lexemes)]
+         [todo? (any-contains? text human-noise)]
+         [score (clamp01 (- (+ (if (> generic-family-ratio 0.08) 0.20 0.0)
+                              (if (>= regular-name-count 5) 0.18 0.0)
+                              (if (>= error-count 6) 0.18 0.0)
+                              (if (and (> (length nonblank) 40) (> generic-family-count 8)) 0.14 0.0))
+                           (if todo? 0.10 0.0)))]
+         [evidence (append (if (> generic-family-ratio 0.08) (list (str "generic scaffold name ratio " generic-family-ratio)) '())
+                           (if (>= regular-name-count 5) (list (str "regular generated-style names " regular-name-count)) '())
+                           (if (>= error-count 6) (list (str "dense error-handling terms " error-count)) '())
+                           (if (and (> (length nonblank) 40) (> generic-family-count 8)) '("large scaffold-like block") '())
+                           (if todo? '("TODO/FIXME/debug markers present as counter-evidence") '()))])
+    (sig "cadence-code-patterns" "code" score 0.18 "medium"
+         "Cadence-style code pattern strategies matched generic names, regular naming, or scaffolding"
+         evidence
+         "framework conventions, generated code, tutorials, and mechanical scaffolds can match these patterns")))
 
 (def (line-lengths lines) (map string-length (filter (lambda (line) (not (blank? line))) lines)))
 (def (blank-gaps lines)
@@ -853,7 +883,8 @@
          [eligible? (and (pair? files) (pair? lines) (or (= min-lines 0) (>= (length lines) min-lines)))]
          [sim-pair (similarity-signal lines hashes)]
          [raw-signals (if eligible?
-                          (list (message-signal subject body adds) (code-signal lines) (structure-signal paths adds dels lines)
+                          (list (message-signal subject body adds) (code-signal lines) (cadence-code-pattern-signal lines)
+                                (structure-signal paths adds dels lines)
                                 (cadence-diff-shape-signal files paths adds dels)
                                 (semantic-alignment-signal subject body lines)
                                 (car sim-pair) (history-signal adds time (parent-time repo parent) (author-times repo revs author-email))
diff --git a/tests/fixture-smoke.sh b/tests/fixture-smoke.sh
index c513141..39a61df 100755
--- a/tests/fixture-smoke.sh
+++ b/tests/fixture-smoke.sh
@@ -55,6 +55,8 @@ printf '%s\n' "$json" | grep -q '"attribution_status":"matched-note-range"'
 printf '%s\n' "$json" | grep -q '"unmatched_recorded_attribution":\[\]'
 printf '%s\n' "$json" | grep -q '"metadata_hits":\["codex","openai"\]'
 printf '%s\n' "$json" | grep -q '"category":"code"'
+printf '%s\n' "$json" | grep -q '"name":"cadence-code-patterns"'
+printf '%s\n' "$json" | grep -q 'regular generated-style names'
 printf '%s\n' "$json" | grep -q '"category":"structure"'
 printf '%s\n' "$json" | grep -q '"name":"cadence-diff-shape"'
 printf '%s\n' "$json" | grep -q '"name":"semantic-alignment"'