Add Android cross-WPO discovery records

ober

72b3ab43c3935cc2486ab050a70658428e70a910

diff --git a/data/anti-patterns.sexp b/data/anti-patterns.sexp
index 11908ff..b875f4e 100644
--- a/data/anti-patterns.sexp
+++ b/data/anti-patterns.sexp
@@ -5180,4 +5180,21 @@
    ("tools"
      "jerboa_check_balance"
      "jerboa_repair_balance"
-     "jerboa_balanced_insert")))
+     "jerboa_balanced_insert"))
+ (("advice"
+    .
+    "Either delete the wrapper and let member code call the top-level helper, or give the wrapper a distinct Kotlin name. After regeneration, grep generated Kotlin for `private fun foo(...): ... { return foo(...) }` and run an emulator launch/logcat check.")
+   ("avoid"
+     .
+     "Do not add a private member wrapper with `(kotlin-name foo)` whose body calls `foo` with the same arity when a top-level `foo` helper exists.")
+   ("id" . "typed-kotlin-same-name-wrapper-recursion")
+   ("kinds" "android" "debug-error" "test")
+   ("pattern"
+     .
+     "private fun ([A-Za-z0-9_]+)\([^)]*\).*return \1\(")
+   ("severity" . "high")
+   ("tags" "typed-kotlin" "android" "kotlin-name"
+     "stack-overflow" "generator")
+   ("title" . "Typed Kotlin Same-Name Wrapper Recursion")
+   ("tools" "jerboa_check_balance" "jerboa_verify"
+     "jerboa_run_tests" "adb logcat" "uiautomator dump")))
diff --git a/data/cookbooks.sexp b/data/cookbooks.sexp
index d7bdb91..9e1b5e2 100644
--- a/data/cookbooks.sexp
+++ b/data/cookbooks.sexp
@@ -7137,4 +7137,31 @@
      "repair_balance" "workflow")
    ("title"
      .
-     "Recover when a .ss file becomes unbalanced (dropped/extra paren)")))
+     "Recover when a .ss file becomes unbalanced (dropped/extra paren)"))
+ (("code"
+    .
+    "# tools/build_android_embedded_rules.sh
+JERBOA_WPO_SCHEME="${JERBOA_WPO_SCHEME:-$JERBOA_VENDOR/build/chez/$(uname -m | sed 's/arm64/tarm64osx/;s/x86_64/ta6osx/')/bin/$(uname -m | sed 's/arm64/tarm64osx/;s/x86_64/ta6osx/')/scheme}"
+
+JERBUILD_BINARY_OBJ_DIR="$JERBUILD_OBJ_DIR" \
+JERBUILD_BINARY_KEEP_OBJ_DIR=1 \
+JERBOA_WPO_SCHEME="$JERBOA_WPO_SCHEME" \
+"$JERBOA_BIN" jerbuild binary \
+  --libdirs "$ANDROID_RULES_BUILD_DIR/lib" \
+  --cc "$TARGET_CC -shared -fPIC" \
+  --csv-dir "$CSV_DIR" \
+  --xpatch "$XPATCH" \
+  --os-libs "-llog -lm -ldl" \
+  --main-c "$ANDROID_APP/src/main/jni/originaltactics_rules_jni.c" \
+  "$ROOT/sfb/android-service-main.ss" \
+  "$OUTPUT_SO"
+
+# jerbuild.ss subprocess selection
+# If JERBOA_WPO_SCHEME is set, run: $JERBOA_WPO_SCHEME --script cross-wpo-compile.ss
+# Otherwise fall back to the packaged jerboa runtime.") ("id" . "android-cross-wpo-use-host-scheme") ("imports")
+   ("notes"
+     .
+     "When Android cross-WPO fails with `Exception in lookup_c_entry: invalid index 51`, reproduce with a one-line .ss file. If raw host Chez Scheme can run the generated cross-wpo helper but `dist/jerboa runtime` cannot, teach jerbuild to honor `JERBOA_WPO_SCHEME` for isolated WPO helpers and rebuild `vendor/jerboa/dist/jerboa` so the packaged multicall binary sees the source change.")
+   ("tags" "android" "cross-build" "wpo" "jerbuild" "xpatch"
+     "lookup_c_entry")
+   ("title" . "Use Host Chez Scheme for Android Cross-WPO")))
diff --git a/data/error-fixes.sexp b/data/error-fixes.sexp
index 30b4bf9..1fdacd7 100644
--- a/data/error-fixes.sexp
+++ b/data/error-fixes.sexp
@@ -2943,4 +2943,41 @@
      "Internal (def ...) appeared where only expressions are allowed. Most often a missing closing paren ABOVE glued the next top-level form into the previous form's body. Run jerboa_check_balance first; if unbalanced, restore with `git checkout -- <file>` and redo with jerboa_balanced_insert, or use jerboa_repair_balance. If balanced, move the def to the start of the body or rewrite as let/let*.")
    ("id" . "invalid-context-for-definition-glued-forms")
    ("pattern" . "invalid context for definition")
-   ("type" . "compile")))
+   ("type" . "compile"))
+ (("code_example"
+    .
+    "JERBOA_WPO_SCHEME="$PWD/vendor/jerboa/build/chez/tarm64osx/bin/tarm64osx/scheme" \
+vendor/jerboa/dist/jerboa jerbuild binary \
+  --csv-dir vendor/jerboa/.chez-cross-tarm64le/lib/csv10.4.0-pre-release.4/tarm64le \
+  --xpatch vendor/jerboa/build/chez/xc-tarm64le/s/xpatch \
+  entry.ss output.so")
+   ("explanation"
+     .
+     "A packaged Jerboa multicall runtime can fail when loading a Chez xpatch and running Android cross-WPO helpers. The same generated helper may succeed under the raw host Chez Scheme binary.")
+   ("fix"
+     .
+     "Reproduce with a minimal .ss cross build. If raw host Chez succeeds, run jerbuild WPO helper subprocesses with a host Scheme override such as JERBOA_WPO_SCHEME=/path/to/build/chez/<host>/bin/<host>/scheme, rebuild dist/jerboa so the change is embedded, then rerun the Android APK build.")
+   ("id" . "android-cross-wpo-lookup-c-entry-invalid-index")
+   ("pattern"
+     .
+     "Exception in lookup_c_entry: invalid index 51")
+   ("type" . "cross-build"))
+ (("code_example"
+    .
+    ";; Bad inside MainActivity typed template:
+(def (truncateForLogLocal (text : String) (limit : Int32)) : String
+  (modifiers private) (kotlin-name truncateForLog)
+  (truncateForLog text limit))
+
+;; Fix: delete this wrapper and call the top-level truncateForLog directly.")
+   ("explanation"
+     .
+     "A Typed Android template emitted a private member with `(kotlin-name helper)` whose body calls `helper` with the same arity. Kotlin resolves the call to the member instead of the top-level helper, causing infinite recursion.")
+   ("fix"
+     .
+     "Remove the duplicate member wrapper or rename it so calls resolve to the intended top-level helper. Regenerate Kotlin, confirm no `private fun helper(...): ... { return helper(...) }` remains, rebuild, install, launch, and check logcat.")
+   ("id" . "typed-kotlin-helper-wrapper-stack-overflow")
+   ("pattern"
+     .
+     "java\.lang\.StackOverflowError:.*MainActivity\.(truncateForLog|autoEventDelayMillis|hudActionLabel|seekingSortBucket|shortDefenseKind|isInterestingEvent)")
+   ("type" . "android-runtime")))