Document parity handoff frontier

ober

d0ef0bd110c0da4cb09fa65b1f728449e6bd15fa

diff --git a/HANDOFF_OPUS_4_8.md b/HANDOFF_OPUS_4_8.md
index 90f02a5..22608cb 100644
--- a/HANDOFF_OPUS_4_8.md
+++ b/HANDOFF_OPUS_4_8.md
@@ -1,10 +1,11 @@
 # Opus 4.8 Handoff: jerboa-semgrep Semgrep Parity
 
-Date: 2026-05-29 04:11 MDT
+Date: 2026-05-29 04:16 MDT
 Workspace: `/Users/user/mine/jerboa-semgrep`
 Sibling upstream Semgrep checkout: `/Users/user/mine/semgrep`
 Packaged Semgrep oracle: `/Users/user/.local/bin/semgrep`
-Base HEAD before this checkpoint: `55798c9 Report upstream current oracle errors`
+Base HEAD before this final handoff update:
+`d2a56c1 Broaden generic regex oracle coverage`
 
 The user wants this project carried forward until the pure Jerboa port reaches
 Semgrep parity. Continue from the current frontier below. Do not restart broad
@@ -28,7 +29,7 @@ language parser coverage.
 
 ## Files In This Checkpoint
 
-This handoff commit should include:
+The recent code checkpoint includes:
 
 ```text
 HANDOFF_OPUS_4_8.md
@@ -246,6 +247,98 @@ Refresh the frontier with:
 SEMGREP_CURRENT=/Users/user/.local/bin/semgrep LIST_MISMATCHES=1 MAX_DIFFS=0 tests/oracle/upstream-sweep.sh
 ```
 
+## Unsupported Upstream Frontier
+
+The upstream `tests/rules` same-basename corpus currently contains 444 rule
+configs. The sweep can compare 243 because `target_for_rule` only considers
+these target suffixes:
+
+```text
+py js json txt generic gem ts tsx
+```
+
+That leaves 201 upstream configs outside the current oracle surface. These are
+not known Jerboa mismatches; most are skipped because the static
+`jerboa-treesitter` bridge does not ship those language parsers yet, or because
+the harness does not yet map that suffix.
+
+Skipped target-extension buckets:
+
+```text
+42 java
+29 php
+23 cpp
+18 scala
+16 go
+11 rs
+ 7 tf
+ 7 jl
+ 6 c
+ 5 move
+ 5 dart
+ 4 rb
+ 4 kt
+ 3 yl
+ 3 xml
+ 3 dockerfile
+ 2 html
+ 1 tpl
+ 1 swift
+ 1 mustache
+ 1 ejs
+ 1 cs
+```
+
+Representative skipped cases by extension:
+
+```text
+java: cp_private_class_attr, cp_private_class_attr1, cp_private_class_attr2,
+      cp_private_class_attr3, metavar_comparison_bitand,
+      metavar_comparison_bitnot, metavar_comparison_bitor,
+      metavar_comparison_bitxor, metavar_comparison_java_float_suffix,
+      metavar_comparison_multi_and, metavar_comparison_multi_or,
+      metavar_name_imported_entity_java
+php:  TODO_taint_messy_sink, attributes_match_multiple, metavar_call,
+      metavar_call_case_insensitive, metavar_pattern_fake_toks,
+      metavar_pattern_fake_toks1, metavar_regex_include,
+      metavar_type_non_prim_php, metavar_type_str_eq_php,
+      metavariable_pattern_php, misc_php_new, misc_php_new_taint
+cpp:  assign_in_cond_expr_cpp, cp_lambda, cpp_array_inits, ctor_cpp,
+      metavar_template_type_arg, metavar_type_multi_types_cpp,
+      metavar_type_simple_cpp, placement_new_cpp, prim_obj_init_cpp,
+      string_vs_char_ptr_cpp, taint_cpp_for_each, taint_cpp_ptr_field
+scala: df_scala_expr_block, metavar_type_not_scala, pattern_matching,
+       taint_foreach1, taint_match_constructor, taint_match_constructor2,
+       taint_match_constructor3, taint_match_literal, taint_match_literal2,
+       taint_match_literal3, taint_match_literal4, taint_match_tuple
+go:    cast_symbol_prop, cp_subtraction, cp_subtraction1, ellipsis_in_case,
+       inside_test, int_binop, metavar_comparison_str,
+       metavar_type_func_param_go, metavar_type_not_go, not_found_exn,
+       regression_uniq_or_ellipsis, struct_tags
+rs:    macro_arg_taint, metavar_type_not_rust, misc_macro_call,
+       rust_macro_token_args, taint_implicit_return, taint_labels_rec,
+       taint_param_pattern, taint_rust_returns, taint_unsafe_block,
+       tainted_pattern_lval, typed_metavar_not_rust
+```
+
+Lower-count skipped buckets are still important for parity because they exercise
+target language behavior that generic matching cannot cover: Terraform (`tf`),
+Julia (`jl`), C, Move, Dart, Ruby, Kotlin, YAML (`yl`), XML, Dockerfile, HTML,
+template/PHP (`tpl`), Swift, Mustache, EJS, and C#.
+
+Parser coverage constraints:
+
+- `src/semgrep/lang.ss` currently recognizes parse-supported ids
+  `json`, `python`, `js`, and `ts`.
+- TypeScript and TSX use the JavaScript parser fallback; decorated members are
+  handled by a targeted scanner fallback, not a full TypeScript grammar.
+- `/Users/user/mine/jerboa-treesitter` currently vendors only JSON, Python, and
+  JavaScript static languages. It is not a git repository, so changes made there
+  will not be committed with this repo unless a separate packaging step is
+  created.
+- Java is the largest skipped bucket. Adding Java parser support would unlock
+  42 same-basename upstream fixtures before broader harness changes.
+
 ## Recommended Next Target
 
 There is no known Jerboa mismatch in the current 243-case sorted upstream
@@ -256,6 +349,10 @@ validation because their upstream test YAML contains an empty `metadata:`.
 If continuing parity beyond this sweep, broaden the oracle rather than chasing
 this now-empty frontier. Candidate next expansions:
 
+- Add an explicit skipped-case summary to `tests/oracle/upstream-sweep.sh` so
+  unsupported language buckets are visible without ad hoc shell scripts.
+- Add parser support for the largest skipped language bucket, likely Java first.
+  Be careful with the non-git `jerboa-treesitter` dependency.
 - Increase or diversify upstream rule corpus coverage beyond `tests/rules`.
 - Add parser-specific cases for TypeScript/TSX beyond the current JavaScript
   parser fallback.