For Agents

Reverse-chronological session log. Newest entries at top, grouped by date (YYYY-MM-DD). Each bullet: one piece of work, short summary, wikilinks to docs touched. Updated by obsidian-documenter on every project doc write. Read by historian at bootstrap.

2026-06-09

  • GFW free satellite does NOT track PortWatch → Strategy C SHELVED (terminal). Tested Global Fishing Watch as a FREE satellite proxy for PortWatch’s Hormuz transit count (the last cheap idea after terrestrial came up empty). Access that worked: GFW 4Wings TILE endpoint (heatmap MVT) is public/anonymous (the report endpoint is WAF-blocked for long Bearer JWTs); dataset public-global-presence:v4.0, daily, Hormuz bbox = 6 z10 tiles summed → vessel-HOURS/day. Verdict: NOT a usable proxy. Correlation (n=424 days, 2025-01→2026-02): daily Pearson r=0.33 / Spearman 0.30, weekly 0.24; by quarter Q1-25 0.55, Q2-25 0.25, Q3-25 0.63, Q4-25 −0.07 (crisis), Q1-26 0.61. Fundamental mismatch: GFW measures vessel-PRESENCE (vessel-hours, incl. anchored/loitering) while PortWatch counts TRANSIT-CALLS (crossings) — they anti-correlate in a crisis (vessels anchor near the strait → GFW up, fewer transit → PortWatch down), which is exactly the regime we’d bet on, so the signal collapses/goes negative precisely when it matters. Bias ~1350 vh/day vs ~92 transits/day (14.6×, different metrics). Cadence DID check out (latest 2026-06-05 on 2026-06-09 = 4-day lag, daily updates, would lead PortWatch’s Tue publish by up to 6 days) — but r=0.33 is too weak to trade. Strategy C final status: SHELVED — every cheap/free path dead (free terrestrial = zero Gulf coverage; GFW free satellite = wrong metric/anti-correlates; Data Docked area endpoint terrestrial-only/blind to Hormuz; VesselFinder ~€330 floor + ~€46/poll; Spire/Kpler enterprise). Edge remains REAL (prices lag PortWatch publish ~4 days; outcomes lock before publish) but only enterprise satellite captures it — uneconomic for a ~1k/clip regime-dependent edge. Artifacts preserved (collector built/clippy-clean/46-tests-green at ~/coding/hormuz_bet; spec + plan under docs/superpowers/). Resume triggers: strait normalizes (higher counts + deeper liquidity) OR a cheap TRANSIT-grade (not presence) satellite source appears. Session arc: Strategy A built→ran→INCONCLUSIVE; Strategy C edge-real-but-uncapturable-cheaply → both correctly killed for ~$0. In hormuz-bet-strategy-c-shelved.
  • Side finding (flag): PortWatch’s March-2026 collapse may be partly a DATA-FEED degradation, not a real event. PortWatch n_total dropped ~90% on 2026-03-01 (~90–130/day → 3–17/day) and stayed low through May, but independent GFW vessel-presence did NOT collapse the same way → the recent low counts may be partly artifactual, which (a) muddies the earlier “wartime low-count regime” framing and (b) makes the target even noisier to predict. Recorded as a caveat on the settlement series in hormuz-bet-portwatch-data; re-check if C is ever resumed. In hormuz-bet-strategy-c-shelved.
  • VERIFIED LIVE: free & cheap TERRESTRIAL AIS have ZERO Strait-of-Hormuz coverage → Strategy C Stage-0’s free-data premise is DEAD. Tested two terrestrial sources over the Hormuz box (lon 56.20–56.95 / lat 26.25–26.70): aisstream.io (free WSS) flooded a global box (instant Aegean vessel) but returned 0 messages for the Hormuz AND a wider Gulf box over 90s/30s; MyShipTracking (free trial, api/v2/vessel/zone bbox, Bearer) returned {"status":"success","data":[]} (0 vessels) even at minutesBack=1440, while a Rotterdam sanity box returned 286. Both are coverage gaps (no contributor receivers near the strait), not auth/code — which is exactly why PortWatch runs on satellite AIS (Spire). Also fixed a real bug: aisstream delivers AIS as WebSocket BINARY frames not Text — our client only handled Text and silently dropped everything (fixed in src/ais/aisstream.rs). Stage-0 code stays built/clippy-clean/46-5 green but has no free feed to run on. Reframe: don’t test “does satellite see Hormuz” (PortWatch’s 3–10/day satellite counts already prove it) — the open question is whether a self-polled real-time satellite feed (Data Docked, ~€1.25/credit or ~€140/mo) can count transits ahead of the weekly Tue publish, confirmable with a ~€5–10 pay-per-credit spot-check before any subscription. Decision pending: pay for satellite (~€140/mo standing cost, small/regime-dependent edge) vs shelve C; the edge itself survives (prices lag PortWatch ~4 days). In hormuz-bet-terrestrial-ais-zero-hormuz.

2026-06-08

  • Strategy C, Stage 0 BUILT & run-ready — the free, local, ~1-week terrestrial-AIS tracking pre-check (the cheap go/no-go before the expensive fleet+satellite Stage 1). New modules in the existing hormuz_bet crate: geo (ray-cast polygon + provisional Hormuz box lon 56.20–56.95 / lat 26.25–26.70), ais (Observation + AisSource trait + aisstream.io WSS client), transit (in-polygon + 48h per-MMSI UTC dedup + teleport/spoof filter + type cache → daily counts), cstore (SQLite our_daily_counts + pw_snapshots, first-published = earliest snapshot), track (de-biased 7-day-SUM error + residual autocorr + ballpark + stationarity-vs-GFW + verdict), gfw (GFW dark-event jamming proxy), portwatch::snapshot (reuses A’s client), plus the ais-collect daemon + track-report bin. Built subagent-driven (5 units, two-stage review each + final holistic). State: clippy -D warnings clean, cargo test --lib 46 passed / 5 ignored, warning-free build. NOT a git repo. Plan docs/superpowers/plans/2026-06-08-hormuz-strategy-c-stage0.md; spec docs/superpowers/specs/2026-06-08-hormuz-strategy-c-ais-calibration-design.md. In hormuz-bet-strategy-c-stage0.

  • Two existential red-team fixes wired into the live verdict path: (1) GO gates on the de-biased 7-day cumulative SUM error (window_sum_error over pairs.windows(7)), NOT daily error — a systematic undercount accumulates over the week (market resolves on the weekly sum) and is now caught; (2) a non-stationary gap (|stationarity_r| ≥ 0.6 vs the GFW jamming proxy) forces NO-GO before the GO gate. Plus first-published scoring (earliest snapshot), coverage-% exclusion (sub-0.5 days dropped, never zero-filled), and silent-dead-feed hardening (zero-message UTC day forces coverage=0 + live [FEED SILENT] warning after ~2min). In hormuz-bet-strategy-c-stage0.

  • Two reality-coupled verification steps before trusting counts (do on first run): the aisstream.io envelope field names + bbox corner order, and the GFW v3 Events API dataset id/body/response schema, are transcribed from spec best-guess and MUST be confirmed against live payloads via the #[ignore] tests (cargo test -- --ignored --nocapture; needs free AISSTREAM_API_KEY + GFW_API_TOKEN). Gate meaning: collect ~7–10 days on an always-on host, then track-report after the next PortWatch Tuesday drop covers them → GO green-lights Stage 1 (fleet+satellite), NO-GO kills C (or escalate data), INCONCLUSIVE keeps collecting. Open owner items: sign off / refine the provisional polygon (geo::hormuz_zone) and choose the always-on host. In hormuz-bet-strategy-c-stage0.

  • Strategy C kill-tests PASSED → GO (conditional). Two zero-cost paper kill-tests on real free data (PortWatch daily series + CLOB price history) before building any AIS collector. (1) Outcomes ARE sensitive to pending-day info — weekly totals resolved within 2–4 ships of bucket boundary (May 11: 44 vs 40; May 18: 42 vs 40), locked in by Day 6. (2) The info is NOT priced — winning bucket stayed cheap through the weekend, repriced only the day AFTER the Tue PortWatch drop (May 11: ~19.5% on Sat May 16 → 90%+ May 20, ~5x; June 1: flat ~52.5% → ~+90% in 5 days). Prices REACT to PortWatch, don’t ANTICIPATE it — empirically refutes the “already priced” pre-mortem objection. EXCLUDE the daily-threshold markets (40+/60+/80+): pure regime bets, daily count never >29, zero AIS edge. Reframe: AIS gives the ACTUAL count, so bar = “within ~2–4 ships,” not “within a bucket.” Caveats: n=2 priced markets (directional only, need 10+/~25+ drops), ~1k capacity, regime-dependent, and the untested gate = can live AIS track PortWatch n_total within ~2–4 ships (terrestrial may undercount mid-strait → satellite probe now first-class). Next: Milestone 1 AIS pilot. In hormuz-bet-basis-risk and hormuz-bet-backtesting.

  • LIVE RUN executed end-to-end (read-only) → VERDICT: INCONCLUSIVE at both fee levels. Ingested 2708 PortWatch days (2019→present); golden spine PASSES live (week-of-May-11 reconstructs to the real 40-59 bucket). fee_k=0: strategy +737 (53 trades), bootstrap-5% −1461, Brier 0.093, negctrl −2032; fee_k=0.072: +488 (51), boot5% −1710. Sensitivity ±0/10/25% all INCONCLUSIVE (stable). Numbers in hormuz-bet-build-spec1.

  • Honest read: NO robust edge → do not deploy capital. Positive point PnL but bootstrap-5% deeply negative (CI straddles 0); tiny sample (~2-3 resolved weekly events, anomalous wartime regime). Damning tell: late-determinacy (high-confidence) trades LOST (−1300) while early made money (+2037) — backwards from a real nowcaster edge, so +737 is noise not skill. Structural cause: count markets resolve on PUBLIC PortWatch data the market also sees (little informational edge) and are thin. INCONCLUSIVE routes to the Spec #2 paper-trade; the engine is a reusable instrument that gains power as more weekly markets accrue. In hormuz-bet-build-spec1, context in hormuz-bet-backtesting.

  • Three live bring-up fixes (all sound): (1) PortWatch date is ArcGIS esriFieldTypeDateOnly → serializes as STRING “YYYY-MM-DD” not epoch-millis; fixed Attrs.date to Option<String> + NaiveDate::parse_from_str (Gamma/CLOB structs verified correct, no change). (2) perturb panicked on rel=0.0 (empty gen_range(-0.0..0.0)) → short-circuit clone when rel==0.0. (3) METHODOLOGY: negative-control gate must be ONE-SIDED — negc.total().abs() <= bound wrongly flagged a LOSING control as a leak; a losing blind control is EXPECTED against efficient markets, only a spuriously WINNING control is a leak. Fixed to negc.total() <= bound; flipped a misleading NO-GO to the honest INCONCLUSIVE. Reusable rule for all backtest neg-controls. In hormuz-bet-build-spec1.

  • Final state after live run: cargo test --lib 30 passed / 3 ignored, clippy -D warnings clean, golden test passes live. Not a git repo (owner rule). In hormuz-bet-build-spec1.

  • Spec #1 “PortWatch resolution nowcaster — backtest to go/no-go” BUILT and fully reviewed (Rust crate hormuz_bet, 10 modules, subagent-driven TDD + two-stage review each): clippy -D warnings clean, cargo test --lib 30 passed / 3 ignored, golden integration test compiles. NOT yet RUN against live data → verdict still pending a network run. As-built architecture + learnings in hormuz-bet-build-spec1.

  • Architecture: one daily-count model (Negative-Binomial + EWMA log-level + day-of-week, shared per-draw level path for cross-day correlation) exposed to all three market types via a pure resolve reused for BOTH forecasting and settlement (cannot diverge); portwatch::as_of point-in-time with a leakage-guard test; three-way GO/NO-GO/INCONCLUSIVE verdict gate. In hormuz-bet-build-spec1.

  • High-value learnings captured in hormuz-bet-build-spec1: (1) negative-control must read ≈0 against an efficiently-priced market — shrinking size_cap defangs it; fix is pricing the near-certain bucket ~0.99. (2) Fee consistency: charged unconditionally on BOTH win and loss in ex-ante EV and ex-post settle (matches PM shares*0.072*p*(1-p) at trade time) — refuted a reviewer who wanted to skip the fee on losses; removed a redundant BtCfg.fee_k. (3) rtk proxy suppresses test stderr — bypass with rtk proxy cargo test -- --nocapture. (4) sqlx uses runtime query API (no DB at build), local SQLite store.

2026-06-07