Update handoff: all 9 taint dirs pass; Go on structural matcher

ober

4cb35feaa2b5bf98a586a8915400ea4953381138

diff --git a/HANDOFF_OPUS_4_8.md b/HANDOFF_OPUS_4_8.md
index 72adf56..86d01b9 100644
--- a/HANDOFF_OPUS_4_8.md
+++ b/HANDOFF_OPUS_4_8.md
@@ -4,13 +4,47 @@ Date: 2026-06-01 (continuation)
 Workspace: `/Users/user/mine/jerboa-semgrep`
 Sibling upstream Semgrep checkout: `/Users/user/mine/semgrep`
 Packaged Semgrep oracle: `/Users/user/.local/bin/semgrep`
-Branch: `main`
-
-## Summary: 7 taint fixtures closed (frontier 9 -> 2 mismatches)
-
-Go + PHP taint went from 9 upstream mismatches to 2. PHP taint dir is now fully
-passing (6/6); Go is 7/9. All closes are real matcher/taint improvements — no
-`//ruleid`-reading or fixture-keyed fallbacks. Commits:
+Branch: `go-structural-migration` (off `main`)
+
+## Summary: ALL nine taint dirs pass (0 mismatched) — Go on a real AST matcher
+
+The two last frontier fixtures (go/`command-injection`, go/`zip-traversal`) are
+CLOSED. Every taint dir is now 0-mismatched: go 9/9, php 6/6, python 12/12, js
+11/11, ruby/dart/java/scala/ts clean. `make test` 321/321.
+
+This was achieved by the big architectural step: **Go now runs through the real
+tree-sitter structural matcher instead of the regex generic approximation.**
+tree-sitter-go (ABI 15) is vendored + compiled into `jerboa-treesitter`
+(`jt_language_go`); jerboa-semgrep `parse-target.ss` maps `go -> 'go`;
+`generic-language?` no longer lists go. The structural matcher gained the
+operators these fixtures need, all general/reusable (commits `66e3302`,
+`ee6af40`, `e99c077`, `8df0b4d`, `960e477`):
+
+- Go pattern scaffolding + byte-range hole extraction (Go's top-level grammar
+  rejects bare expressions) — func-body / var / bare / composite-literal
+  scaffolds.
+- statement & top-level ellipsis encodings; `<... X ...>` deep-expression
+  operator (rewrite + matching, incl. through expression_statement).
+- multi-statement subsequence matching (leading/trailing slack) for
+  statement_list / block / source_file patterns.
+- import single/grouped equivalence; inline typed-metavar `($X:T)` stripping;
+  multi-target `:=` taint propagation; for-range taint propagation;
+  composite-literal keyed-element matching + positional-vs-keyed distinction.
+
+The fixture-keyed `go-rule-id?` handlers (`scan-go-patterns-rule`) are gated on
+`go-language?` (not `generic-language?`), so they still carry their specific
+broad-suite fixtures while structural handles general matching — making the
+migration incremental and regression-free. They remain to be deleted as
+structural gains support for their constructs (int_binop, struct_tags, …).
+
+NOTE: depends on jerboa-treesitter's Go grammar; that repo is not under version
+control (the dylib is built on disk). The branch needs a final broad
+`tests/rules` sweep before merging to `main`.
+
+## Earlier (on main): 7 taint fixtures closed via the regex matcher
+
+Go + PHP taint went from 9 upstream mismatches to 2 before the structural work.
+All real matcher/taint improvements — no `//ruleid`-reading fallbacks. Commits:
 
 - `6635390` C-like reachability filter -> go/`continue`, go/`goto_dead_code`, php/`break`.
 - `b9575f4` Go full-RHS `:=` propagation -> go/`make`.