For Agents
Living index of themes for this project. Each H2 is a topic; bullets are wikilinks to related notes. Updated by
obsidian-documenterwhen documenting work. Read byhistorianat bootstrap. Topics kept alphabetical.
Architecture & pmv2 Split
- pmv2-rearchitecture — the pmv2 monolith (
polymarket_fetch) retiring → split into independent service repos (producers → executor → notify), NATS JetStream spine, sharedpmv2-contractscrate as the seam. Position Manager = the executor (consumes NATS directly, gates off/dry/live + caps + breaker, signs EIP-712, POSTs CLOB; Mode OFF). Trade wire-contract v2 (signed off by weather): weather emits a READY BUY entry-order topmv2.order.weather.entry,pricing="limit"(limit_price≤0.95 +size_shares), entry-only, sizing moved to producers (notional/limit_price, default $50).sourceis a free String (wrong value → silentMode::Off). Supersedes the old single-streamWEATHER_SIGNALS/docs/signal-schema.mdv1 envelope - pmv2-reorg-and-weather-as-2026-06-22 — the same reorg from the Asian-weather (
weather_as) side + the authoritative AS-lane current state.position_manager= the SINGLE execution authority (polymarket_fetchretires); producers (cohort_algo/crypto_algo/us_weather_algo/as_weather_algo) own strategy+sizing and publish READY entry-orders;pmv2-contractsenvelope with apricingdiscriminator (limitdirective = weather/crypto vsderived= cohort), subjectspmv2.order.<source>.<entry|exit>, weather entry-only, TTR gate exempt for Directive. Repos: weather-bet →pmv2-weather-us-algo(/coding/pmv2/us_weather_algo, US+research) + new PRIVATEpmv2-weather-as-algo(/coding/pmv2/as_weather_algo,e9415dc). AS lane =source=weather_asonpmv2.order.weather_as.entry, modes OFF/dry, self-measure standalone, publish leg waits onpmv2-contracts. Companion to pmv2-rearchitecture - weather-as-babylon-identity-2026-06-22 — the AS lane’s babylon coordination identity: handle
weather_asprovisioned 2026-06-22, per-repo gitignored 0600.mcp.jsonshadowing the global babylon MCP (no globalBABYLON_TOKEN); split of the oldweatherhandle intoweather_as(Asian) +weather_us(US) - weather-as-deploy-pattern-b-2026-06-23 — AS-lane deploy convention: containerized Pattern B via the
appsAnsible role (image→GAR,deploys/apps.ymlentry +deploy-apps.ymldispatch, OTel env auto-injected). Run shape FLIPPED 2026-06-23 from two OnCalendar cron jobs to a continuouskind=servicerunningpython shadow_engine.py --loop(scan everySCAN_INTERVAL_SECS+ daily settle atSETTLE_HOUR_UTC) — driven by the fleet-wide #354 boot-announce directive (#362 envelope totelegram.outbound, sha/title from GIT_SHA/GIT_TITLE build-args per #358) + symmetry with weather-US’s--loop. Lane is NO LONGER NATS-free: boot announce needsNATS_URL+ weather_as NKey (NATS_NKEY_SEED, PUBtelegram.outbound); orders stay OFF - weather-as-dry-publish-arm-2026-06-25 — AS-lane DRY publish ARMED 2026-06-25: pin
9a07960→e5521c4+WEATHER_AS_PUBLISH=1env. New binary is env-gated default OFF; ongate_admitpublishes the pmv2-contracts entry envelope topmv2.order.weather_as.entryonce per market/day (self-measure dedup). Money safety intact (weather_as=dry_run, globaldry_run, PM gates at build+sign). NATS NKey +PMV2_ORDERSwildcard already in place from prior session. Kill switch = unset env + re-push secret + redeploy - pmv2-source-id-3way-invariant-2026-06-23 — the
source_id3-way invariant:position_managerkeys on the wiresourcevalue, NOT the agent/repo handle (handle renames are free). Producer wiresource==pmv2_autotrade_sources.source_id== NATS subject segment must stay equal or the lane silently fail-closes toMode::Off. GOTCHA: US lane handle becomesweather_usbut its wiresourceSTAYSweather(intentional mismatch — do not “fix”); AS lane consistent (weather_as/weather_as). source renames = coordinated 3-way change, ping @positionmanager first
Backtesting & Research Data
- intraday-drift-study-naive-no-go — 112 market-days × 1,224 buckets intraday-price + forecast + realized-high dataset (
research/data/, reportresearch/report.md); drift is real but naive buy-open/sell-+50% = −27% net (survivorship bias); v2 re-analysis off same cache: forecast-conditioned (NEAR ±1°C of lead-2 forecast) + 18:00 exit = +9.6% blended → CANDIDATE - weather-netcost-precheck-2026-06-19 — net-of-cost EV pre-check on the gate’s OOS test: gated (P≥0.68) +0.140/ pessimistic, gate lift +0.317/ is the convergence-gated number, later shown to be an optimistic ceiling by the win-label re-score
- weather-gate-winlabel-2026-06-19 — the WIN-label re-score (discharge of shadow-rehearsal caveat #1): selecting on P(WIN) not P(convergence) collapses EV ~+0.14/** at matched 8.5% admit, and the model loses to a per-city win-rate lookup (+0.0939) / ex-ante-only (+0.0772) / ties ungated (+0.0553) —
entry_pricealone (AUC 0.7136) beats it (0.6838). Disguised price-picker; CONDITIONAL-GO → LIVE-MEASUREMENT-ONLY (no capital, no Rust). True-resolution OOS coverage 74.7%, biased with the signal.research/gate/{build_win_gate.py,winlabel_ev.json,gate_win_metrics.json} - weather-lag-distribution-2026-06-19 — unbiased full-population reprice-lag study, N=28,664 (every cheap-Yes 0.55–0.95, no highest-paid cap), all 6 shards, critic-reviewed. Realized ex-ante hit rate ~34.4% (not 63–67% — ~49% never reprice to 0.97); converged lag median 37.1min (p25 8.2 / p75 81.6 / p90 127.6).
research/reports/weather-lag-distribution-2026-06-19.md+lag_distribution.json - wx-lag-pipeline-bug — data-integrity backstory behind the repricing-lag distribution study (
research/copytrade/top50/lag/): the published 180-min convergence numbers were re-derived at analysis time but never persisted (lag_distribution.jsonshowed stale 120-min); 180-min is fully recoverable fromreprice_lag_minwithout CLOB re-pull; shard_2 (16.7% of population) missing, concentrated in headline cities → per-citynand city ranking are provisional - weather-lookahead-trap-2026-07-02 — the look-ahead trap (binding backtest rules): proxy-timed entries (gate at 15:30 modal price, enter earlier prints) inflated EV ~2–3× — AS +0.455→+0.145/; overlays (0.90 cap / flatten / PT rejection) were test-set-selected. Rules: entries at-or-after ALL gating info exists; never tune a parameter on its scoring window. The clean causal n=67 +29.9%/trade backtest survives
Bug Fixes & Debugging
- fix-resolve-twc-primary-source — TWC as primary resolution source; IEM demoted to cross-check fallback; fixed ~50% silent skip rate on market resolution
- wx-lag-pipeline-bug — convergence-horizon baking bug in the 6-shard reprice-lag pipeline:
convergedbaked at 120-min whilereprice_lag_minmeasured at 180-min (the 120/180 mismatch); report’s 180-min numbers never written back tolag_distribution.json. Fix = compute convergence inaggregate_lag.pyviais_converged()againstCONVERGE_HORIZON_MIN(aggregator authoritative, immune to stale per-shard baked flags). Gotcha: nolib.py— fetch logic inlined & drifted per shard - weather-as-selfmeasure-pnl-fixes-2026-06-23 — resolves HANDOVER PART 2 M7/M8/M9 + L7 self-measure P&L bugs (TDD, 44 tests Python 3.14). M7 reject fills above producer’s actual limit
min(0.95, current_at_lock+PRICE_BUMP)(limit_price threaded lock→realizable_fill); M8 never infer void from price —_resolve_payoffbinary-only-when-closed&binary,settleforce-voids as STAKE-REFUND (net_pnl=-cost) only afterMAX_SETTLE_AGE_DAYS; L7_RES_CACHEre-keyed per(slug,token)to stop sibling-token poisoning; M9 records gross+net with mode-aware slippage (live=0, replaySLIPPAGE_REPLAYhalf-spread). 2026-06-24 (@ 7939da2): live--loopcrash — Python%Zstrptime CANNOT parse abbreviated zone names (PDT/JST/CST); a strftime→strptime round-trip inlock_from_traceValueError’d on every locked city and aborted the whole scan tick. Fix: reconstruct local datetime fromlock_ts+ IANA zone (fromtimestamp(ts, utc).astimezone(ZoneInfo(zone))). Coverage lesson: tests mockedlock_from_traceitself so the round-trip went uncovered — added real JST+PDT regressions; surfaced by the deploy-mode-OFF dry-run (46 tests green)
Coordination & Babylon
- weather-as-babylon-identity-2026-06-22 — the lane’s babylon identity (
weather_as), theweather→weather_as/weather_ushandle split, channel subscriptions (general, pmv2, weather-shadow, weather-jetstream), the inherited coordination thread (#302/#306/#313/#315 → 337), and open coordination blockers (#302 deploy convention,PMV2_ORDERS+pmv2_autotrade_sourcesrowsource_id=weather_as, OTel before live) - pmv2-source-id-3way-invariant-2026-06-23 — @positionmanager pmv2 #340: the wire
sourceis a 3-way contract (producer emit ==pmv2_autotrade_sources.source_id== NATS subject) — any drift silently fail-closes the lane toMode::Off. Renaming asource_id= coordinated 3-way change → ping @positionmanager FIRST. Acked AS-side in pmv2 #344; weather_us must coordinate before touching its source
Copy-Trade & Wallet Reconnaissance
- copytrade-top-weather-traders — v1: on-chain recon off the small weatherbot.fi board; real money = late near-certain settlement, buy-cheap/sell-pop = the worst (huskyvs LAST)
- weather-top50-decypher-2026-06-19 — v2: official leaderboard 87→65→50, critic-corrected. “Capacity, not return” (1.52M, ROI inversely correlates with capital); ≤0.95 fillable edge plausible but NOT proven (3/10 wallets clear latency, lag right-skewed, winners paid ABOVE book 11–13/15); doctrine = “detect, don’t mirror” (Tier A copyable vs Tier B confirmation-only carry whales); design-only
copytradeNATS source spec; all PnL FIFO-inferred - weather-lag-distribution-2026-06-19 — the unbiased follow-up that settles v2’s fillability open items → weak-GO. Full-population (N=28,664, no highest-paid cap): realized hit rate ~34.4% (not 63–67%, ~49% never converge); thesis FLIP — winners pay a ~2-tick PREMIUM not a discount (fair_gap +0.02, 75% above same-instant book) → convergence-timing edge bought slightly rich; binding gate = net-of-cost recovery (live rehearsal); per-wallet unbiased lag medians HondaCivic 8.6 / vip68 10.7 / Happening9014 20.6
Deployment & Infrastructure
- weather-as-deploy-pattern-b-2026-06-23 —
pmv2-weather-as-algo→polymarket-infravia containerized Pattern B (appsAnsible role; no host venv/systemd). Image → GAReurope-west3-docker.pkg.dev/<project>/levandor-apps/pmv2-weather-as-algo:<sha>; deploy =deploys/apps.ymlentry + dispatchdeploy-apps.yml; role auto-injects OTel env (zero-config once Python OTLP SDK init’d inmain()). Run shape FLIPPED 2026-06-23 from two OnCalendar crons (--scan/--settle) to a continuouskind=servicerunningpython shadow_engine.py --loop(cohort scan everySCAN_INTERVAL_SECSdefault 1800 + daily settle at/afterSETTLE_HOUR_UTCdefault 12, both env-tunable). Reason: fleet-wide #354 boot-announce directive (continuous service announces cleanly ONCE on boot, cron can’t) + weather_as NKey PUBtelegram.outbound(#366) + symmetry with weather-US’s--loop. Boot announce = canonical #362 envelopecomponent: pmv2-weather-as-algo started with version: <sha> <title>, sha/title from GIT_SHA/GIT_TITLE build-args (#358). Lane is NO LONGER NATS-free — announce needsNATS_URL+ weather_as NKey seed (NATS_NKEY_SEED, PUBtelegram.outbound); orders stay OFF (no--live); announce best-effort (missing creds →startup_announce:false, never crashes). Built TDD, 22 tests green on Python 3.14 (shadow_engine.py,publisher.pyDRY_connect_and_publish,DockerfileARG/ENV + CMD--loop,build-push.ymlgitmeta). Container artifacts in-repo:Dockerfile(python:3.13-slim),.dockerignore,build-push.yml(WIF→GAR). WARNING: accumulated P&L validates plumbing not edge (open bugs M7/M8/M9). Pending from deploy/Andras: WIF provider + SA literals for CI, the weather_as NKey, Andras’s terraformci_github_reposgrant
Forecasting & Edge Thesis
- weather-strategy-validated-plan — the validated edge: fixed 12:00Z close lands pre-peak for US/London → forecast game; quantified 6-8c at first 0.90 crossing decaying to ~0.4c at 1h; >=0.90 in final 2-3h = 100% YES (113 market-days)
- polymarket-weather-market-structure — why next-day station Tmax (whole °C, 1°C buckets) is a skill-rich, validatable edge surface
- weather-top50-decypher-2026-06-19 — the honest fillability re-read: 99c carry NOT fillable; candidate edge = repricing-lag layer (cheap-Yes post-METAR-lock) but unproven — right-skewed lag means a 20-min gate rarely fires, and winners paid ABOVE the book (risk-taking vs lag-harvest unresolved); best slice = highest-temp buckets, post-local-peak, ~4–9h pre-resolution, London + Asian-hours + NYC/Atlanta, select by observed lag
- weather-lag-distribution-2026-06-19 — the unbiased study that resolves the above → weak-GO. Winners pay a ~2-tick PREMIUM (fair_gap +0.02, 75% above book) — convergence-timing edge bought rich, NOT discount-to-fair; realized hit ~34.4% (~49% never converge); gate must be EX-ANTE (city/session/METAR — observed lag is look-ahead); robust tier-A city universe = london/nyc/seoul/hong-kong/atlanta/paris/wuhan; binding gate = net-of-cost recovery of the premium
Maker & Liquidity Rewards
- weather-prior-corrections-2026-07-02 — LR pools on weather EXIST (prior belief wrong): 467 temp markets with
rewardsDailyRate>0, ~55/mkt/day; top pools seoul-lowest 1,010 / munich 703; min 20–50 shares inside 4.5c spread; 25% maker rebate (weather is fee-bearing) - weather-strategy-verdicts-2026-07-02 — the EU maker/LR pilot spec: madrid+paris quoting vacuums (12–18c spreads), blocked on GTD/GTC + cancel() live-test + quote manager/self-cross guard; inventory cap $150–200, no modal-bucket quoting 15:00–18:00; pass = LR accrual ≥2× inventory losses, cancel p95 <5s, zero self-crosses
Market Structure & Resolution
- weather-strategy-validated-plan — fixed 12:00:00Z book close (the why-an-edge-exists insight); resolution-mirror spec (Wunderground daily-history, named ICAO, whole °F/°C, local midnight-midnight, UMA ~2h liveness/$750 bond); wrong-station traps (Dallas=KDAL, Houston=KHOU, Denver=KBKF, Moscow=UUWW, Chicago=KORD, skip Hong Kong); global=Wunderground vs US/CFTC=NWS CLI
- polymarket-weather-market-structure — 11 neg-risk 1°C buckets, Wunderground ICAO airport resolution, whole-°C precision, endDate timing
- fix-resolve-twc-primary-source — TWC is the authoritative Polymarket resolution source; IEM is cross-check only
- weather-as-selfmeasure-pnl-fixes-2026-06-23 — void economics: a Polymarket void/invalid market is a STAKE REFUND (P&L≈0), NOT a mid payout;
closed:truecan coexist with mid prices during dispute/settlement so don’t infer resolution fromoutcomePricesalone; multi-market events poison sibling-token caches unless keyed per (event,token) - weather-prior-corrections-2026-07-02 — stations pinned engine-critical (paris = LFPB Le Bourget NOT LFPG; london = EGLC City NOT Heathrow; denver = Buckley SFB; istanbul/moscow/tel-aviv via NOAA weather.gov; HK = HKO 0.1°C); universe now 48 cities + a lowest-temperature series; US 2°F buckets/0.01 tick vs non-US 1°C/0.001 tick; °C boundary gate fixable via national tenths feeds (DWD/FMI/IMGW/JMA-AMeDAS/SYNOP-OGIMET) for 7/8 EU cities;
api.weather.compublic key polls the WU resolution truth directly (~30-min, ToS-gray)
NATS & Signal Publishing
- pmv2-rearchitecture — the v2 transport: stream
PMV2_ORDERSoverpmv2.order.<source>.<entry|exit>; PM binds ONE durable pull consumer onpmv2.order.>(explicit ack,Nats-Msg-Id=iddedup,duplicate_window). Subject builders + envelope live in the sharedpmv2-contractscrate. Supersedes the singleWEATHER_SIGNALS/weather.signalsstream - wx-signal-nats-nkey-auth —
wx-signalSignalPublisherNATS/JetStream publisher;async-nats0.49 NKey auth (ConnectOptions::with_nkey(seed)sync+infallible;nkeysdefault feature; lazy seed validation at connect →ConnectErrorAuthentication); auth precedenceNATS_NKEY_SEED>NATS_CREDS> no-auth; dormant (None) unlessNATS_URLset; no secret logging - weather-top50-decypher-2026-06-19 — design-only
copytradesignal source (not a new stream): rides existing WEATHER_SIGNALS, source-routedsource="copytrade", cohort-first-mover K-of-N in window W,max_price ≤0.95(cohort worst-entry clamped), UUIDv5Nats-Msg-Iddedup aligned with the live engine; independent confirmer not a mirror - pmv2-source-id-3way-invariant-2026-06-23 — the NATS subject segment
pmv2.order.<source>.entryis one leg of the 3-waysourceinvariant (producer emit == operatorsource_id== subject); locked subjects: USpmv2.order.weather.entry, ASpmv2.order.weather_as.entry. A drifted subject → PM sees an unknown source → lane silently fail-closes toMode::Off
Polymarket API
- polymarket-weather-market-structure — Gamma
public-searchvs/events?slug=, field-availability quirks (volume vs liquidity), clobTokenIds - wx-market-prices-history — CLOB
/prices-historyendpoint:interval=max(caps ~410 pts) andstartTs/endTswindowed variants; YES-token ID required;fidelityin minutes - wx-market-trades-client — data-api
/tradesendpoint: per-token trade history,asset= YES-token ID; note different base URL from CLOB - weather-prior-corrections-2026-07-02 — Gamma
clobRewards/rewardsDailyRatefields carry the LR pools;feeType=weather_fees+ true fee formula0.05·p·(1−p);api.weather.compublic-web-key endpoint as a direct WU-truth poll
Project Overview
- weather-bet — project entry point, status, the pmv2 split context; repo now
pmv2-weather-us-algoat/Users/levander/coding/pmv2/us_weather_algo/ - weather-bet-live-status — ⭐ authoritative current state: live engine, pmv2 split, v2 wire contract, dry-test gate saga, repo rename/move, open items
- pmv2-rearchitecture — the multi-service design + trade wire-contract v2
- wx-research-crate —
wx-researchworkspace crate added for intraday-drift research work
Research Pipeline & Data Clients
- wx-market-prices-history —
ClobPriceHistoryinwx-market: read-only CLOB price-history client;history()interval-capped,history_window()unix-timestamp windowed; keeper component for research + live trader - wx-market-trades-client —
TradesClientinwx-market: read-only data-api trades client;all_by_asset()auto-paginator (PAGE=500, cap 20k);de_flex_i64flex deserializer;Sideenum (Buy/Sell)
Rust Gotchas & Tooling
- wx-signal-nats-nkey-auth — edition-2024 gotcha:
std::env::set_var/remove_varareunsafe fn, and[workspace.lints.rust] unsafe_code = "forbid"makes them uncompilable in tests (evenunsafe {}—forbidoverrides#[allow]) → can’t mutate env in tests; workaround = assert read-order side effects instead. Also clippy-pedanticused_underscore_bindingfires when a_-prefixed binding is actually used. Plusasync-natssync/infalliblewith_nkeyvs async/falliblewith_credentials_file
Strategy Research
- weather-strategy-validated-plan — VALIDATED GO plan: late-settlement / repricing-lag. Fixed 12:00Z book close lands before the afternoon peak for US/London → winning bucket only 0.40-0.57 at close (0.43-0.61 gap to 1; rank on LIVE PRICE not volume. Tier-1 NYC/Atlanta/Chicago/Miami. Validate-first: OOS Python backtest of the 6-8c edge → then live Rust nowcaster. Full report
research/reports/weather-trader-deep-dive.md - intraday-drift-study-naive-no-go — naive buy-open/sell-pop REJECTED (−27% net, survivorship bias); v2 forecast-conditioned (buy buckets AT/just-ABOVE forecasted high, hold to 18:00 convergence) = +9.6% mean, 80% LCB −6.9%, n=125 → live CANDIDATE not GO; two levers (forecast-proximity + exit-timing) stack; confirms 2026-06-11 nowcast/information-timing pivot
- copytrade-top-weather-traders — copy-trade recon of the top Polymarket weather traders (on-chain trades via
data-api/trades?user=): real money = late near-certain settlement (HondaCivic 1); 2nd winner = early forecast value (Railbird/dpnd); buy-cheap/sell-pop is ONLY huskyvs+ShyGuy1 and huskyvs is LAST in PnL → independently confirms the nowcast/information-timing edge (trade the repricing lag on a bucket you can see has won) - weather-top50-decypher-2026-06-19 — v2 copy-trade decypher (official leaderboard, 87→65→50, critic-corrected): “capacity, not return” — whales hold 70% of capital at the LOWEST ROI (6.2%); the ≤0.95 own-edge is plausible but NOT proven and the dry-rehearsal is reframed as the deciding experiment (discount-to-fair vs residual risk); “detect, don’t mirror” copy doctrine
- weather-lag-distribution-2026-06-19 — unbiased full-population settlement of the fillability question → weak-GO. Sizes the repricing-lag layer honestly: realized hit ~34.4% (size for ~65% miss), winners pay a ~2-tick PREMIUM (not a discount), binding gate = net-of-cost recovery in the live rehearsal; gate ex-ante on city/session/METAR (tier-A: london/nyc/seoul/hong-kong/atlanta/paris/wuhan), never on observed lag
- weather-gate-winlabel-2026-06-19 — the honest-criterion verdict on the whole Asian-afternoon chain: re-scoring the gate on P(WIN) gives only +0.0604/$, loses to a per-city win-rate lookup, ties ungated → CONDITIONAL-GO downgraded to LIVE-MEASUREMENT-ONLY. Treat the strategy as “favorite-buying with a cost cushion,” not a weather-timing model; no capital / no Rust until a live loop beats an ungated/per-city baseline
- pmv2-reorg-and-weather-as-2026-06-22 — the Asian chain packaged as the
weather_asproducer: validated edge (gated net-of-cost EV ~+0.14/$ beats per-city +0.09 / ungated +0.06 on backtest) but NEVER RUN LIVE — single-season (~11d June), thin (n 14–19/latency), convergence-selected (optimistic ceiling), book reprices past us ~40–50%. End-of-stage-3; the forward dry-run (self-measure, NATS-independent) is the next milestone - weather-strategy-verdicts-2026-07-02 — ⭐ the post-skeptic lane verdicts (2026-07-02 synthesis): US taker PILOT NOW (100 clips, gate ≥0.60, cap 0.95, hold-to-settle, fee-fix first, pass n≥50 & roi_lcb_80>0); EU taker **DROP** (8 D3c depth, 1-min whale sweeps; reopen via a 16:00–20:30-local depth cron); EU maker PILOT after cancel()/GTD; Asia RESEARCH-MORE (Seoul fold at 65% lockout; CN/Tokyo decided by a lock-timed replay); cheap tails + adjacent-flip-tail DEAD. Taker capacity ceiling $1–3k/day US-wide
- weather-lookahead-trap-2026-07-02 — why today’s headline EVs (+0.455 AS / +0.191 US per $) were fantasy: proxy-timed entries + test-set-selected overlays; the binding causal-backtest rules; what survives (gate direction, hold-to-settle, the n=67 +29.9%/trade clean backtest)
Storage & Infrastructure
- weather-bet-supabase-migration — SQLite → Supabase Postgres migration; dedicated
weather_betschema (fleet convention), idempotent embeddedschema.sqlbootstrap (notsqlx::migrate!), SQLite→Postgres strict-typing gotchas, session-pooler-:5432-not-:6543connection rule,testcontainers/testkit-feature test harness, @deploy handoff
Workspace & Crates
- wx-research-crate —
wx-researchcrate skeleton (branchresearch/intraday-drift): 7 module stubs,plotters+csvworkspace deps, local deps onwx-core/wx-market/wx-data - wx-signal-nats-nkey-auth —
wx-signalcrate’s NATS publisher (crates/wx-signal/src/nats.rs): NKey/creds-file/no-auth precedence + the edition-2024set_vartest gotcha for this workspace (edition = "2024",unsafe_code = "forbid")