Commit 89e354e on main of wowjeeez/pmv2-crypto-algo. Second discrete pre-live hardening pass targeting the migrate, binance, and emit crates. All gates clean: fmt + build + clippy -D warnings + 7 new tests pass.
Blocker Fix
migrate/src/main.rs — Compile-Time Migration Embedding
Replaced a runtime fs::read_to_string loop that searched three candidate paths for each .sql file with a compile-time constant:
const MIGRATIONS: &[(&str, &str)] = &[
("0001", include_str!("../migrations/0001_....sql")),
// ... all five
];All five migrations (0001–0005) are now embedded via include_str!. There is no CWD dependency at runtime, making the binary safe for systemd units where the working directory is not guaranteed.
High-Severity Fixes
emit.rs — NATS NKey Authentication
NATS_URL now requires a companion NATS_NKEY_SEED environment variable. Connection uses:
async_nats::ConnectOptions::with_nkey(seed).connect(url).awaitHard error at startup if NATS_URL is set but NATS_NKEY_SEED is absent. Shadow mode (when NATS_URL is unset) is unchanged.
async-nats 0.37 NKey API
async_nats::ConnectOptions::with_nkey(seed: String).connect(url: &str).await
binance.rs — Staleness Gate Clock Source Fix
In stream_once, after parse_trade succeeds, the receive timestamp is now stamped via pp.as_of = Utc::now(). The staleness gate in emit.rs ((now - bt).num_seconds() <= 30) therefore compares local clock to local clock — previously it mixed exchange-reported milliseconds with a local Utc::now() comparison.
Also fixed: .unwrap() on timestamp_millis_opt replaced with .single().unwrap_or_else(Utc::now) to avoid a panic on ambiguous DST-fold timestamps (rare but possible after leap-second adjustments in test environments).
Medium-Severity Fixes
emit.rs — Cached Active Market (Hot-Path Latency)
discover_active_market() has been removed from the event loop. A background tokio task polls every 30 seconds and writes results into a tokio::sync::watch channel. The fire path reads market_rx.borrow().clone() — zero HTTP latency on the critical path.
polymarket.rs — Outcome Label Hardening
Confirmed live labels from Gamma API (btc-updown-5m-1781901900) are ["Up", "Down"]. Two defensive fixes applied:
.trim()called before.to_lowercase()on each label.warn!log withoutcomes = ?outcomeson any no-match, making mislabelled markets loud.token_downvalidated as a parseableu128(parity with the existingtoken_upvalidation).
polymarket.rs — HTTP Hardening
- User-Agent header
"crypto-shortterm-emitter/1.0"set on both the Gamma and CLOBreqwestclients. - 5-second timeout added to the
poll_bookreqwestclient (was unbounded).
Low-Severity Fixes
emit.rs — RUST_LOG Default
EnvFilter::new(filter) with a "info" fallback when RUST_LOG is unset. No std::env::set_var call (avoids the Clippy set_var warning in multi-threaded code).
emit.rs — ON CONFLICT Confirmed Correct
INSERT ... ON CONFLICT (window_id) DO NOTHING was already present in the emitted_signals insert. Confirmed correct; no change needed.
New Tests (7 Added)
| Test | Crate | Verifies |
|---|---|---|
migrate::tests::migration_sequence_includes_all_five | migrate | include_str! const covers migrations 0001–0005 |
observe::tests::binance_staleness_uses_receive_time | observe | pp.as_of set to local clock after parse_trade |
observe::tests::cached_market_window_mismatch_skip | observe | watch-channel market skipped if window_id mismatches |
observe::tests::label_match_trimmed_and_cased | observe | " Up " and "UP" both resolve to the correct token |
observe::tests::label_no_match_is_none | observe | unrecognised label returns None (no silent wrong token) |
observe::tests::on_conflict_window_id_semantics | observe | DO NOTHING path is idempotent for duplicate window_id |
observe::tests::nats_url_without_seed_is_hard_error | observe | startup hard-errors when NATS_URL set but NATS_NKEY_SEED absent |
Live Outcome Label Reference
Confirmed from Gamma API market btc-updown-5m-1781901900:
["Up", "Down"]Index 0 = Up (YES). The outcome-label matching introduced in crypto-shortterm-emit-guardrails (commit bc38734) now handles whitespace and case variation correctly.
Pre-live Discipline Pattern
This is the second in a series of pre-live code review passes on money-path code. Pattern:
- Build — code written, tests written, CI clean.
- Review — explicit severity-tagged audit of every code path that touches money, IO, or state.
- Fix — changes committed with full test coverage and gate check.
- Delta review — planned for the moment before the live flip to catch any regressions introduced by the fixes themselves.
Related
- crypto-shortterm-emit-guardrails — Review Pass 1 (commit
bc38734): 13 money-safety fixes on data model + emit.rs full rewrite - crypto-shortterm-phase1-emit — phase-1 emitter architecture and pmv2 schema alignment
- crypto-shortterm-data-sources — Gamma API, CLOB, Binance feed details
- crypto-shortterm — project overview