Handoff: scope-aware reachability is the next taint-engine blocker (verified)

ober

521575c0da9431596c935428846336f9c90a11c6

diff --git a/HANDOFF_OPUS_4_8.md b/HANDOFF_OPUS_4_8.md
index dc1a69b..b334e14 100644
--- a/HANDOFF_OPUS_4_8.md
+++ b/HANDOFF_OPUS_4_8.md
@@ -184,15 +184,29 @@ languages, so closing them is the tip of the larger work:
    - `java-field-decl-matches`: a `$T $L=$R` pattern matches a field_declaration,
      so field initializers propagate taint.
    - enhanced-for propagator: `for ($T $L : $R) {...}` taints the loop var.
-   Result: 8/18 java taint fixtures now flow structurally; removed the `tainting`,
+   - `java-parse-method-pattern` + `java-rewrite-param-metavars`: the parameter
+     -pattern preprocessor — gives bare `$X`/`...` params a synthetic type so
+     `public void $F(..., $X, ...)` parses; the matcher treats a synthetic
+     formal_parameter named `__sg_ellipsis__` as an ellipsis and `__sg_mvar_X` as
+     a metavar bound to the target param. Param-SOURCES now match like Semgrep.
+   Result: 8/18 java taint fixtures flow structurally; removed the `tainting`,
    `java-iterator-missed-propagation`, and `documentbuilderfactory` overfit clauses
    (java 42/42, smoke 321/321 each step).
-   STILL handler-side (the harder taint features, the `test` rule-id group can't be
-   retired until ALL its fixtures pass): type-aware assume-safe (numbers1/booleans1),
-   best-fit-sink ranges (sink11), getter/setter sensitivity, lambda propagators
-   (lambda1/propagator_lambda), jpa-sqli (propagator4), tainted-file-path, and FQN
-   resolution (final_globals2, metavariable-resolution-test: Foo -> org.foo.Foo).
-   The same engine retires the other languages' taint handlers + unblocks dart.
+
+   **The next fundamental blocker is SCOPE-AWARE REACHABILITY (verified).** With
+   param-sources matching, `taint_assume_safe_numbers1` still fails because the
+   general engine's source→sink reachability is *positional/global*, not
+   per-method: every method's `$X` param reaches every `sink(...)`, so test1's
+   sink is (wrongly) flagged by test3-10's params. Confirmed empirically — a
+   numeric-typed-source filter (`source-state-numeric-typed-param?`, classifies
+   `int`/`long`/`Integer`… correctly) drops the right sources but findings persist
+   because cross-method non-numeric sources still reach. So the order is: (1)
+   per-method (CFG/scope) reachability, THEN (2) numeric/boolean source+value
+   type-classification, THEN (3) numeric-result value-analysis (`Integer.valueOf`,
+   `+`, `!=`). Each is real dataflow/type-inference work; together they're a
+   multi-day engine, and the `test` rule-id group needs ALL of them + best-fit-sink,
+   getter/setter, lambda, jpa, FQN before its overfit clause retires. The same
+   engine retires the other languages' taint handlers + unblocks dart.
    - a few per-language pattern hard-cases (go constant-folding/struct_tags, php
      metavar-call/non-prim-type, rust macro-call, kotlin named-ellipsis).