The authoritative current-state snapshot for the weather effort after the pmv2 ecosystem reorg (per Andras’s Miro board) and the carve-out of the Asian-weather (weather_as) lane into its own private repo. This supersedes the single-repo weather-bet framing in weather-bet and weather-bet-live-status: weather-bet is now two repos under a multi-producer / single-executor architecture, and the AS lane is a lean Python producer at end-of-stage-3 (validated prototype, never run live).
Companion note (US-lane / cross-service view)
pmv2-rearchitecture covers the same reorg from the US producer + cross-service side (the
limitarm of the contract, US sizing, the dry-test gate saga, the cohort/crypto/notify framing). This note is the Asian-weather (weather_as) producer view — theas_weather_algomodule map + the validated-but-never-live AS edge. The two are consistent.
Current state in one place (2026-06-22)
Architecture: pmv2 is now multi-producer → single-executor.
position_manageris the SINGLE execution authority — it consumes signals from NATS and owns gate (off/dry/live) + caps/breaker + sign + POST + record;polymarket_fetchretires. Producers own strategy + sizing and publish READY entry-orders:cohort_algo,crypto_algo,us_weather_algo(the former weather-bet), and the newas_weather_algo.telegram_connectorrides alongside. Repos: weather-bet was renamed →pmv2-weather-us-algoand moved to/coding/pmv2/us_weather_algo(US engine + the shared research history). The new PRIVATEpmv2-weather-as-algolives at/coding/pmv2/as_weather_algo(committede9415dc, pushed) — the lean Python AS producer. AS lane:source=weather_as, subjectpmv2.order.weather_as.entry. Pipeline: observe IEM → causal lock → match bucket → convergence-gate ≥0.68 → size ) — but single-season, thin, convergence-selected, and NEVER RUN LIVE (see the maturity warning below). Stage: end-of-stage-3 (validated prototype). The forward dry-run is the next milestone.
1. The pmv2 ecosystem reorg
Andras’s Miro board reshapes pmv2 from a tangle of per-strategy executors into a clean multi-producer / single-executor topology. Strategy and execution are now separated by a NATS wire contract.
position_manager = the SINGLE execution authority
There is now exactly one component that touches the CLOB / signs / spends money: position_manager. Its responsibilities (and only its):
- Consume entry-orders off NATS (per-
sourcesubjects). - Gate by mode —
off(ack-and-skip) /dry(alert + record, no order) /live(place order). - Risk — apply caps + a circuit breaker before anything goes out.
- Sign the order with the CLOB-holding wallet identity.
- POST to the CLOB.
- Record the fill / outcome.
polymarket_fetch (the legacy sibling that previously held both copy-trade signal logic and execution) retires into this — execution moves wholesale to position_manager. This is the single chokepoint where caps, the breaker, and the live/dry/off switch live, so no producer can ever place an order directly.
Producers own strategy + sizing and publish READY entry-orders
Each producer is responsible for its own strategy AND its sizing decision, and emits a READY-to-execute entry-order (not a raw signal the executor has to size). The producers:
| Producer | Lane | Pricing kind |
|---|---|---|
cohort_algo | copy-trade / cohort first-mover | derived (reference_price + conviction → size_usd) |
crypto_algo | crypto short-term | limit (directive) |
us_weather_algo | US weather (the former weather-bet) | limit (directive) |
as_weather_algo | Asian weather (NEW) | limit (directive) |
telegram_connector | operator/notify surface | — |
For Agents
The decisive split:
position_manageris the only writer to the CLOB. Everything else is a producer that publishes a sized, READY entry-order envelope ontopmv2.order.<source>.entryand never signs or POSTs. The formerweather-betis now theus_weather_algoproducer; the newas_weather_algois its Asian sibling. Both are Directive (limit) sources.
Trade wire-contract — the pmv2-contracts crate
Update (2026-06-22, later same day):
pmv2-contractsis now PUBLISHEDThe crate has since been published (
github.com/wowjeeez/pmv2-contracts) — serde + rust_decimal only; holds the envelope types, thePricingenum (limit|derived),Side,SCHEMA_VERSION = 2, and subject builders;sourceis a free String, not an enum (a wrong value silently routes toMode::Off). This unblocks both lanes’ publisher rewrites. The US-side v2 contract sign-off + field-level detail is in pmv2-rearchitecture; US current state in weather-bet-live-status. The “being designed — not yet built” framing below is from earlier the same day.
The producers and position_manager agree on ONE entry envelope, defined in a shared pmv2-contracts crate. Its shape:
- A single envelope with a
pricingdiscriminator (tagged union):limit— a directive: the producer stateslimit_price+size_sharesand the executor places that order verbatim. Used by weather (US + AS) and crypto.derived— the producer handsreference_price+conviction+size_usdand the executor derives the actual limit. Used by cohort.
- Subjects:
pmv2.order.<source>.<entry|exit>— e.g.pmv2.order.weather_as.entry,pmv2.order.weather_us.entry,pmv2.order.cohort.entry. Routing is bysourcein the subject. - Weather is entry-only — the strategy is hold-to-settlement, so weather producers publish
.entryand never.exit. - Time-to-resolution gate is EXEMPT for Directive sources. The executor’s generic TTR guard (don’t enter too close to resolution) does not apply to
limit/directive entries — weather deliberately enters late (near settlement), so the directive sources opt out of that gate.
This crate is the precondition for the AS lane’s publish leg (see §3): as_weather_algo’s publisher.py still emits the legacy wx-signal envelope, and must be rewritten to the pmv2-contracts envelope before position_manager can consume it.
2. Repos — weather-bet is now two repos
| Repo | Path | Visibility | Role |
|---|---|---|---|
pmv2-weather-us-algo (renamed from weather-bet) | /coding/pmv2/us_weather_algo | — | The US engine (wx-signal Rust crate) + the shared research history (research/, research/reports/). The original repo, renamed and moved under pmv2/. |
pmv2-weather-as-algo (NEW, PRIVATE) | /coding/pmv2/as_weather_algo | private | The lean Python AS producer. Committed e9415dc, pushed. Self-contained — no imports back into any research/ tree. |
- The US
wx-signalengine, its Supabase migration, the NATS NKey auth work, and the entireresearch/corpus (decypher, lag, gate, net-cost, win-label, shadow-rehearsal) stay inus_weather_algo. All the vault notes whose repo pointers sayresearch/...now resolve under/coding/pmv2/us_weather_algo/research/.... - The AS producer is a copied, untangled subset — every module is a local copy, deliberately decoupled from the research tree so it can ship as a standalone private producer.
Stale path references across the vault
Older notes (weather-bet-live-status, weather-bet, and the research notes) say
github.com/wowjeeez/weather-betand/Users/levander/coding/weather_bet. Those are the old repo identity. The repo is nowpmv2-weather-us-algoat/coding/pmv2/us_weather_algo(US + research) with the AS lane split intopmv2-weather-as-algoat/coding/pmv2/as_weather_algo. Treat the new paths as canonical.
3. The Asian-weather (weather_as) lane
A self-contained Python producer for Asian-afternoon late-settlement weather markets, carved out of the shadow-rehearsal research into its own repo. It runs the full signal end-to-end and self-measures, independent of execution.
- Source:
weather_as - Subject:
pmv2.order.weather_as.entry - Modes:
OFF/dry
Pipeline
observe (IEM/METAR running-max)
-> causal lock (hour >= 15 + no-rise 90 min) # lock.causal_lock, LOCK_HOUR=15, NO_RISE_SECS=5400
-> match bucket (Gamma event/bucket -> YES token) # engine.build_signal
-> convergence-gate >= 0.68 (sklearn pkl) # gate/predict.py, GATE_THRESHOLD=0.68
-> size $10-30 clip (gate-score-scaled notional) # config.notional_for
-> publish (NATS JetStream entry-order) # publisher.py [WAITS ON pmv2-contracts]
-> self-measure record / settle (fill + net P&L) # selfmeasure.py
Module map (/coding/pmv2/as_weather_algo/)
| Module | Role |
|---|---|
config.py | cities/stations loader, endpoints, lock constants (LOCK_HOUR=15, NO_RISE_SECS=5400), gate threshold 0.68, notional band $10–30, notional_for(gate_score) clip sizing |
lock.py | causal_lock + running-max series (copied from the research engine) |
metar.py | IEM ASOS obs fetch + running-max-of-day builder |
buckets.py | temperature-bucket label parsing + winning-label resolution |
stations.py | Gamma slug builder + station/resolution parsing |
engine.py | Gamma event fetch, bucket→degree match, YES token, CLOB price ladder (/price→/midpoint→/book), build_signal |
gate/predict.py + gate/gate_model.pkl | the convergence gate is loaded here (featurize + predict_proba); pickled with sklearn 1.9.0 / pandas 3.0.3, loads on CPython 3.13+ |
shadow_engine.py | orchestrator: --rehearse / --self-test / --dry-print / --smoke / --live / --settle |
publisher.py | NATS JetStream entry-order publisher + offline dry_print — still emits the legacy envelope (see below) |
fillability.py | causal price-history fetch + causal snap (for self-measure fills) |
selfmeasure.py | record_signal + settle (fill + resolution + net P&L) only — no baseline benchmarking |
asia_stations.json | Asian (+ a few EU/US) station map: ICAO, IEM id, unit, tz |
Standalone vs NATS — the two legs
- Self-measure runs standalone.
--rehearse/--self-test/--dry-print/--settleand the forward dry-run (record_signal+settle) need no NATS —--dry-printneeds no network at all (the deps are still required to unpickle the gate). The dry-run measures fill + resolution + net P&L per row independently of execution. - The publish leg waits on
pmv2-contracts.--smoke/--livepublish to NATS and are dormant unlessNATS_URLis set (plus optionalWEATHER_SIGNAL_SUBJECT,NATS_NKEY_SEED). Butpublisher.pywas copied as-is and still mirrors the legacywx-signalSignalPayload(source = "weather_shadow", subjectweather.shadow, additivemode/gate_scorefields). Before it can publish into pmv2 it needs thepmv2-contractsenvelope rewrite + aposition_managerthat routes onsourceand tolerates the additive fields. This is the blocking dependency for the live wire.
Sizing — gate-score-scaled clip
config.notional_for(gate_score) maps the gate probability across the $10–30 band: frac = (gate_score − 0.68) / (1 − 0.68), clamped to [0,1], notional = round(10 + frac·20, 2). So a just-admitted entry (0.68) clips at 30.
Cohort & exclusions
- 9 of 11 engine cities covered in replay (atlanta, busan, chengdu, paris, qingdao, san-francisco, seoul, shenzhen, taipei). tokyo + wuhan uncovered — IEM rate-limited the China stations before reaching them (alphabetically last).
- Hong Kong is excluded from the runnable cohort: it resolves to the Hong Kong Observatory at 0.1°C precision, not an airport METAR, so it cannot be IEM-rehearsed (
iem_id=null,caveatinasia_stations.json).
4. Validated edge + honest maturity
The edge is the product of a six-stage research chain, each link a separate validated note. Read in order: weather-top50-decypher-2026-06-19 → weather-lag-distribution-2026-06-19 → weather-exante-gate-2026-06-19 → weather-netcost-precheck-2026-06-19 → weather-gate-winlabel-2026-06-19 → weather-asia-shadow-rehearsal-2026-06-19.
| Stage | Note | What it established |
|---|---|---|
| decypher | weather-top50-decypher-2026-06-19 | the money is in capacity, not return; “detect, don’t mirror”; ≤0.95 fillable edge plausible but not proven |
| lag | weather-lag-distribution-2026-06-19 | unbiased reprice-lag (~34.4% unconditional reach@15); winners pay a ~2-tick PREMIUM not a discount; gate must be ex-ante |
| gate | weather-exante-gate-2026-06-19 | lean ex-ante P(tradeable) classifier, OOS AUC 0.795, dominant feature local_hour; threshold ~0.68 |
| net-cost | weather-netcost-precheck-2026-06-19 | gated EV +0.140/ pessimistic; gate lift +0.317/$; edge concentrates in Asian-afternoon cities |
| win-label | weather-gate-winlabel-2026-06-19 | re-scoring the gate on P(WIN) (not convergence) gives only +0.0604/$, which loses to a per-city win-rate lookup (+0.0939) — the convergence EV is an optimistic ceiling |
| shadow-rehearsal | weather-asia-shadow-rehearsal-2026-06-19 | fill-degradation survives (gated net EV ~+0.14/$ at L=5 vs per-city +0.09 vs ungated +0.06); CONDITIONAL GO on a live dry-run, NO-GO on Rust productionization |
The edge is real on backtest — gated net-of-cost EV ~+0.14/$ beats the per-city +0.09 and ungated +0.06 baselines, and survives the worst modelled cost corner.
NEVER RUN LIVE — the maturity caveats are load-bearing
This is a validated prototype, not a live strategy. No capital has ever traded. Five caveats hold it there:
- Single season. The entire edge is measured on ~11 days of June 2026 daily-high markets. No out-of-season / regime-shift evidence whatsoever.
- Thin cohort. Anchored n = 14–19 per latency; per-city n = 1–5. CIs are wide — a feasibility signal, not a sized backtest.
- The gate is convergence-selected ⇒ optimistic ceiling. It selects on
tradeable_10= P(book converges toward ~1.0), not P(win). The win-label re-score (weather-gate-winlabel-2026-06-19) collapses the EV from ~+0.14/ and shows the model does not beat a per-city win-rate lookup. Treat the headline EV as an upper bound, gate scores as a research artifact, not a calibrated live probability.- The book reprices past us ~40–50% of the time. On the locked days, the book is already > 0.95 at entry 40.6% (L=1) / 45.7% (L=5) / 49.7% (L=15) of the time — adverse selection: we miss roughly half the opportunities, and the ones we can enter are the genuinely-uncertain ones.
- Stage = end-of-stage-3 (validated prototype). The next milestone is the forward dry-run (self-measure against live signals), NOT capital. Rust productionization is NO-GO until a larger live sample reproduces positive EV, the gate is re-scored against a true WIN/+EV label, and tokyo + wuhan coverage is filled.
5. Pending / next
Open items (2026-06-22)
- Move the research record into the AS repo — a cross-repo push the user is authorizing (research currently lives in
us_weather_algo; the relevant slice is being carried intoas_weather_algo).pmv2-contractscrate — design + build the shared entry-envelope crate (thepricinglimit/deriveddiscriminator,pmv2.order.<source>.<entry|exit>subjects, Directive TTR exemption).- Publisher rewrite — rewrite
as_weather_algo/publisher.py(and the US engine’s publisher) from the legacyweather.shadow/weather_shadowenvelope to thepmv2-contractsenvelope;position_managerconsumes it routed onsource.- @deploy guidance — deployment guidance for the AS producer.
- Forward dry-run — run
as_weather_algoin dry against live signals to measure realizable fillability + reject rate. This is the capital gate, not the backtest. The self-measure leg can start now (NATS-independent); the publish-into-pmv2 leg unblocks oncepmv2-contractslands.
Related
-
pmv2-rearchitecture — the US-side companion: the same reorg + the v2 trade wire-contract field-level detail (the
limit/derivedarms, subjects,pmv2-contractsnow published, sizing) -
weather-bet — project overview (single-repo framing, now historical)
-
weather-bet-live-status — the live US
wx-signalengine snapshot (theus_weather_algoside) -
weather-asia-shadow-rehearsal-2026-06-19 — the fill-degradation rehearsal that became this lane
-
weather-gate-winlabel-2026-06-19 — the win-label re-score (the optimistic-ceiling discharge)
-
weather-netcost-precheck-2026-06-19 — the net-of-cost EV pre-check
-
weather-exante-gate-2026-06-19 — the ex-ante convergence gate
-
weather-lag-distribution-2026-06-19 — the unbiased reprice-lag study
-
weather-top50-decypher-2026-06-19 — the copy-trade decypher
-
wx-signal-nats-nkey-auth — NATS NKey auth (the transport)
-
polymarket-fetch — the retiring sibling whose execution role moves into
position_manager -
weather-as-babylon-identity-2026-06-22 — the lane’s babylon coordination identity (
weather_ashandle, per-repo.mcp.json, theweather→weather_as/weather_ushandle split, open coordination blockers)