A subtle Solana versioned-transaction (v0) / Address Lookup Table (ALT) trap that decides which feed is authoritative for venue classification in the slv1 rig: static-key scans on raw shreds miss router-wrapped (CPI) swaps whose venue program is ALT-loaded, so the Yellowstone/geyser leg must be the classification authority. Plus the grounding pass’s other pre-implementation corrections.

For Agents

Design rule: the Yellowstone (geyser) leg is the venue-classification authority at match time; the shred side produces a best-effort venue_hint only. Do not scan raw shred-decoded static keys and assume you have caught every venue swap — you will miss ALT-hidden router swaps.

The Trap

Two facts that seem contradictory but are not:

  1. A program ID can NEVER be ALT-loaded for a TOP-LEVEL instruction. The require_static_program_ids feature means sanitize() rejects any transaction whose top-level instruction program_id_index points into the ALT-loaded key range. Top-level program IDs are always in the static key list.
  2. But a CPI-invoked program appears only as an ACCOUNT, and CAN be ALT-loaded. When a router (e.g. a Jupiter-wrapped swap) calls the venue program via CPI, the venue program is not a top-level program ID — it is just an account in the tx’s account list, and that account may be supplied via an Address Lookup Table.

Consequence for a shred-based scanner:

  • Raw shred-decoded transactions carry unresolved ALT references{table, indexes} — not the resolved account keys. Resolving them needs on-chain ALT state.
  • So a client-side static-key venue scan catches direct venue swaps (venue program is the top-level program ID → always static) but is blind to router-wrapped swaps whose venue program is ALT-loaded and hidden inside {table, indexes}.

Design Response (slv1 rig)

  • Yellowstone / geyser leg = venue authority. Its SubscribeRequestFilterTransactions.account_include filter matches resolved keys server-side → no false negatives: a CPI-invoked venue program must be in the resolved account list even when ALT-loaded.
  • Shred leg = best-effort hint only. Computes venue_hint from static keys; knowingly blind to ALT-hidden router swaps.
  • Matcher is NOT venue-pre-filtered on the shred side — all shred events enter; a completed cross-feed match inherits the geyser leg’s venue. Router-wrapped swaps therefore still produce delta rows even when the shred hint missed them.
  • Expiry split: unmatched_hinted (shred classified venue but geyser never delivered → alarming) vs unmatched_other (non-venue + ALT-hidden venue → expected bulk).
  • Fee-payer detection is ALT-proof — the fee payer is always the first static account key, so cohort-wallet fills are spotted on raw shred bytes regardless of routing.
  • Ceiling (increment 2): close the blind spot by resolving hot ALTs from Yellowstone account subscriptions, or by parsing inner instructions.

Additional grounding-pass corrections (2026-07-03)

More material errors caught pre-implementation

  • Venue volume underestimated 10–100×. Real combined venue swap volume ≈ 10⁷–10⁸ matched tx/week (PumpSwap alone ~4–8M swaps/day at Jan-2026 levels), not “low millions/week.” → percentiles come from fixed-size histograms (solv1_delta_hist), NOT raw rows; raw solv1_tx_deltas is 1:100-sampled with 14-day retention.
  • Jito tip_floor API returns f64 SOL, not lamports — and wraps it in a one-element JSON array (Vec<TipFloor>, take [0]); time is ISO-8601. Don’t multiply by 1e9 or mis-index the array.
  • e2-medium is shared-core / burstable (1.0 vCPU sustained) → CPU throttling adds scheduler jitter to arrival-Instant stamps, biasing the exact latency quantity being measured. Use e2-standard-2 (2 dedicated vCPU) for a latency rig (~$25/mo more).
  • SIMD-0525 steps slot time 400→200ms, possibly from ~Aug 2026 → never hardcode 400ms. Decay windows are defined in slots (N+1/N+2); slot duration is measured per run (solv1_feed_stats.observed_slot_ms).