Main recently merged ADR-151 (Miller-Rabin prime optimizations, PR #358)
and ADR-152 is reserved for Obsidian Brain Plugin (ADR-SYS-152), so
renumber the kalshi integration ADR to 153 to avoid collision.
- Rename docs/adr/ADR-151-kalshi-neural-trader-integration.md →
docs/adr/ADR-153-kalshi-neural-trader-integration.md
- Update 5 references: workspace Cargo.toml comment, the two kalshi
crate descriptions, the lib.rs doc-comment, and the ADR title line.
- Resolve .gitignore: keep both trailing additions (.kalshi + bench_data/).
Co-Authored-By: claude-flow <ruv@ruv.net>
New cargo examples under crates/ruvector-kalshi/examples/:
- list_markets.rs
Authenticated GET /markets against the live API. Tested against
api.elections.kalshi.com — returned 100 real markets (sports parlays,
cross-category bundles), proving the REST + sig path end-to-end.
- stream_orderbook.rs
Live WebSocket consumer. Uses ws_client::reconnect_forever +
FeedDecoder and prints canonical MarketEvents. Configurable via
argv tickers, KALSHI_MAX_EVENTS (default 50), KALSHI_WS_URL.
- live_trade.rs
Full live execution runner: WS -> FeedDecoder -> Strategy ->
CoherenceChecker -> RiskGate -> RestClient::post_order. Triple-
gated — requires KALSHI_ENABLE_LIVE=1, KALSHI_CONFIRM_LIVE=yes, and
a non-zero KALSHI_MAX_ORDERS cap before any signed request is
emitted. Conservative defaults: 0.10 Kelly fraction, 10_000¢
bankroll, 5% position cap, 2% daily-loss kill, 500 bps min edge.
Verified to fail-closed without the env flag.
paper_trade.rs:
- Now async (#[tokio::main]) to enable brain I/O in the fill path.
- When BRAIN_ENABLE=1, loads BRAIN_API_KEY from env or gcloud secret
BRAIN_SYSTEM_KEY and calls BrainClient::share per approved order.
- Run output unchanged: 7 intents / 1 coherence block / 6 approvals /
6 receipts / 4 replay segments / 3 retrievable.
Co-Authored-By: claude-flow <ruv@ruv.net>
AttentionScalper now supports a scaled-dot-product attention path when
AttentionScalperConfig::use_sdpa = true. Levels are encoded as
[size_log, side_sign, depth_idx_norm, 1.0] and fed into
ruvector_attention::ScaledDotProductAttention with a fixed pressure
query. The context vector's sign component becomes the signed
imbalance.
- neural-trader-strategies depends on ruvector-attention (default
features disabled so it stays portable).
- sdpa_imbalance() guards NaN/empty inputs and returns 0 on error, so a
misconfigured attention layer cannot corrupt downstream decisions.
- Geometric-decay path remains the default and is unchanged.
- 2 new tests: heavy YES → YES intent, heavy NO → NO intent, both via
the SDPA path end-to-end.
26 strategy tests pass (was 24). ruvector-kalshi 36 tests pass.
paper_trade example unchanged: 6 fills, 4 replay segments, 6 witness
receipts.
Co-Authored-By: claude-flow <ruv@ruv.net>
neural-trader-strategies:
- Depend on neural-trader-coherence.
- New coherence_bridge module: CoherenceChecker wraps a CoherenceGate
and returns CoherenceOutcome::{Pass, Block} around an Intent. On gate
error we fail closed (never authorize actuation). simple_context()
builds a plausible GateContext from a rolling price window.
- Re-export CoherenceDecision, CoherenceGate, GateConfig, GateContext,
RegimeLabel, ThresholdGate, CoherenceChecker, CoherenceOutcome.
- 3 new tests (24 total): healthy context passes, low mincut blocks,
simple_context correctly classifies volatile regime.
ruvector-kalshi:
- Depend on neural-trader-coherence and neural-trader-replay.
- examples/paper_trade.rs rewritten to include coherence pre-check and
replay storage:
FeedDecoder → MarketEvent
→ ExpectedValueKelly.on_event
→ CoherenceChecker.check (ThresholdGate tuned for Kalshi depth)
→ RiskGate.evaluate
→ intent_to_order → NewOrder
→ ReservoirStore.maybe_write(ReplaySegment)
→ InMemoryReceiptLog.append_receipt(WitnessReceipt)
Observed depth is carried across frames so ticker/trade events
inherit the mincut floor from the last snapshot. CUSUM uses only
trade/ticker mids, not per-level snapshot prices.
- Run result: 7 intents emitted, 1 coherence-blocked, 6 risk-approved,
6 witness receipts, 4 replay segments stored and retrievable.
Tests: 60 unit (36 + 24). Live /exchange/status smoke still green.
Co-Authored-By: claude-flow <ruv@ruv.net>
Signer:
- api_key now Arc<str>, signing_key now Arc<SigningKey<Sha256>>. Clone
is O(1) (atomic fetch_add) instead of a 2048-bit RSA deep-copy.
Measured at 75 ns/iter in release (1M iters) — previously bound by
RsaPrivateKey::clone which deep-copies BigUint fields.
RestClient:
- base_url + pre-computed base_path stored as Arc<str>; sig_path_for()
formats against the cached base_path instead of reqwest::Url::parse
on every request. Measured at 14 ns/iter — the old path was a full
URL parse + to_string per call.
- RestClient::clone is also O(1) as a consequence.
Benchmark example:
- examples/bench_signing.rs reports clone / sign / sig_path numbers.
Release numbers on the real Kalshi PEM:
signer.clone 75.5 ns
sign_with_ts 0.78 ms (1284 sig/s — RSA-PSS floor)
sig_path_for 13.9 ns
All 57 unit tests, paper_trade example, and live /exchange/status
smoke test pass on the optimized paths.
Co-Authored-By: claude-flow <ruv@ruv.net>
ruvector-kalshi:
- ws_client: tokio-tungstenite + futures-util. connect() signs upgrade
with RSA-PSS-SHA256; subscribe() sends a typed command; pump_frames()
routes every text frame through FeedDecoder into an mpsc<MarketEvent>
channel; reconnect_forever() does exponential backoff up to 30s.
- brain: pi.ruv.io client. SharedMemory::market_resolution builds a
redacted pattern memory; BrainClient::share POSTs with Bearer auth to
/v1/memories. Debug never leaks key material.
- URL migration: Kalshi moved from trading-api.kalshi.com to
api.elections.kalshi.com; defaults updated. GCS secret bumped.
- tests/live_smoke.rs: #[ignore]-gated GET /exchange/status. Verified
live response: 200 OK, {"exchange_active":true,"trading_active":true}.
neural-trader-strategies:
- coherence_arb: pair-wise price divergence arbitrage. Configure
(reference, mirror) symbol ids; emit YES buy on mirror when the price
gap exceeds min_divergence_bps. Quarter-Kelly sizing.
- attention_scalper: multi-level order-book imbalance with geometric
level decay and EMA smoothing; emits a short YES or NO position when
the smoothed signal crosses abs_threshold. Deterministic, no ML dep.
CI:
- .github/workflows/kalshi-nightly.yml: unit tests, offline validator,
paper-trade example, and live /exchange/status smoke under --ignored.
Tests: 57 unit (ruvector-kalshi 36, neural-trader-strategies 21) + 1
live smoke. All green against the real Kalshi endpoint.
Co-Authored-By: claude-flow <ruv@ruv.net>
New crate ruvector-kalshi: RSA-PSS-SHA256 signer (PKCS#1/#8), GCS/local/env
secret loader with 5-min cache, typed REST + WS DTOs, Kalshi→MarketEvent
normalizer (reuses neural-trader-core), transport-free FeedDecoder,
reqwest-backed REST client with live-trade env gate, and an offline
sign+verify example that validates against the real PEM.
New crate neural-trader-strategies: venue-agnostic Strategy trait, Intent
type, RiskGate (position cap, daily-loss kill, concentration, min-edge,
live gate, cash check), and ExpectedValueKelly prior-driven strategy.
36 unit tests pass across both crates. End-to-end offline validation
confirmed against the real Kalshi PEM via both local and GCS sources.
Co-Authored-By: claude-flow <ruv@ruv.net>
The workspace pins ndarray 0.16 while ruvector-gnn needs 0.17.2.
Keep the explicit version pin and remove the stale comment to avoid
confusion. Other crates still use workspace ndarray (0.16) safely.
Co-Authored-By: claude-flow <ruv@ruv.net>
* feat(brain): DiskANN vector index, AIDefence, content resolution, geo-spatial support
Brain server updates for ruOS v1.1.0:
- DiskANN Vamana graph index (replaces brute-force at 2K+ vectors)
- AIDefence inline security scanning on POST /memories
- Content resolution from blob store on GET /memories/:id and search
- Search dedup by content_hash with over-fetch (k*8, min 40)
- Security scan endpoint: POST /security/scan, GET /security/status
- List pagination with offset parameter and total count
- Spatial memory categories: spatial-geo, spatial-observation, spatial-vitals
- Blob write on create_memory (was missing — content lost)
Validated: 3,954 memories, 100% vectorized, 23ms search, zero drift,
6/6 AIDefence tests, 0 errors over 3 days continuous operation.
Co-Authored-By: claude-flow <ruv@ruv.net>
* fix(brain): resolve merge conflict markers in Cargo.toml and Cargo.lock
Unresolved <<<<<<< / ======= / >>>>>>> markers blocked all CI
(cargo check, clippy, rustfmt, tests, security audit, native builds).
Keep both sides: ruvbrain-sse + ruvbrain-worker bins from upstream
and the new mcp-brain-server-local bin from this branch. Lock file
retains both ruvector-consciousness and rusqlite dependencies.
Co-Authored-By: claude-flow <ruv@ruv.net>
---------
Co-authored-by: ruvnet <ruvnet@gmail.com>
First benchmark comparing all ruvector-core quantization methods against
TurboQuant on standard vector search datasets. 8 configurations, 3 datasets
(GloVe d=200, SIFT d=128, PKM d=384), 3 trials per config with variance.
Key findings:
- Int4 beats TurboQuant MSE on recall at 8x compression (91.2% vs 89.6% R@1)
- QJL correction hurts recall for vector search (9-41% loss)
- PQ with 8 subspaces fails at d=200 (18.2% R@1)
- TurboQuant MSE 3-bit fills unserved 10.7x compression tier (82.0% R@1)
- QuantizedVector::distance() never called during HNSW search
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
GraphDB and GraphStorage: add delete_edges_batch(ids: &[EdgeId]) -> Result<usize>
- Single transaction for all deletes (vs N transactions in sequential delete_edge loop)
- Returns count of edges actually deleted (skips IDs not found)
- Updates edge_type_index and adjacency_index in single pass
- All 17 edge tests pass
- Add FloatArray(Vec<f32>) variant to PropertyValue enum
- Add float_array() constructor and From<Vec<f32>> impl
- Update extract_embedding to prefer FloatArray (direct clone, no conversion)
- Fallback to legacy Array(Float/Integer) format for backward compat
- Add test_neo4j_float_array_property and test_float_array_constructor
- property_value_strategy proptest now covers FloatArray
- Remove dead property.rs (shadow PropertyValue with Bool/Int variants)
Phase 0 implementation revealed that the original PRD §6 targets
(50 ns / 200 ns for is_prime_u64 worst case) were structurally
unachievable in safe Rust on Apple-silicon. Apples-to-apples competitor
benchmark in the same binary on the same machine measured num-prime
0.4.4 at 884 ns vs ours at 15.63 µs — ~17.7× headroom recoverable via
Montgomery reduction in Phase 0.1, but not the ~300× the original target
implied. The 50 ns figure was a pre-implementation estimate that did not
survive contact with measured hardware.
ADR-151 (docs/adr/ADR-151-miller-rabin-prime-optimizations.md)
- Status promoted from "Proposed" to "Accepted (Phase 0 landed
2026-04-16; performance targets revised)".
- New "Phase 0 Findings (2026-04-16)" section documenting what landed,
measurements vs original targets, num-prime competitor baseline, the
revised target band, and Phase 0.1 scope (Montgomery only).
- Explicit rejection of swapping to the empirical 7-witness set:
Sinclair-12 is theorem-proven across all u64; the 7-witness sets in
the literature are empirically tested up to 2^64 but not proven, and
swapping invalidates the A014233(11) canary in the pseudoprime test.
PRD §6 (docs/research/miller-rabin-optimizations/PRD.md)
- Revision header noting the relaxation.
- is_prime_u64(p) worst-case row updated to ≤ 1 µs (was 50 ns) M-series
/ ≤ 4 µs (was 200 ns) WASM.
- New §6.1 "Empirical findings (Phase 0)" with the measurement table
and the num-prime baseline data.
GROK-REVIEW-REQUEST.md (new, 424 lines)
- Self-contained briefing used to obtain external Grok review of the
Phase 0 design and Phase 0.1 plan: §1 binding context, §2 implementation
embedded verbatim, §3 measurements + competitor baseline, §4 four-section
ask (correctness, perf plan ranked, architecture, validation
methodology), §5 response format. Constraints block forbids
"just use num-prime" answers and pins the canary witness set.
Lands the deterministic Sinclair-12 Miller-Rabin u64 kernel and build-time
prime tables under crates/ruvector-collections/, per ADR-151.
Implementation
- src/primality_kernel.rs: shared MR core (mulmod via u128, powmod, witness
loop, prev/next prime). Single source of truth — include!d from both build.rs
and src/primality.rs to keep the build script and runtime kernel byte-identical.
- src/primality.rs: public API — is_prime_u32/u64, prev/next_prime_u64,
prev_prime_below_pow2(k), next_prime_above_pow2(k), ephemeral_prime(seed).
Probabilistic is_prime_u128 gated behind --feature unstable-u128 with
Russian-peasant mulmod, mod_add overflow-safe addition, and LCG-seeded
witness selection.
- build.rs: emits PRIMES_BELOW_2K[57] / PRIMES_ABOVE_2K[57] for k ∈ [8, 64].
ABOVE[64] is a 0 sentinel (no u64 prime > 2^64); k=64 BELOW special-cases
via mr_prev_prime_u64(u64::MAX).
Tests (76 pass; cross-check 0.00s)
- tests/primality_pseudoprimes.rs: pinned A014233 strong pseudoprimes
(entries 4, 5, 11) so any witness-set regression — including dropping
base-37 — fails loudly. SPP_FIRST_11 = 3_825_123_056_546_413_051 is the
canary for base-37 detection.
- tests/table_cross_check.rs: re-validates all 114 emitted table entries
against MR + sweep_odds_strictly_between (iterates the prime gap, not the
range — so even k=63 finishes instantly).
- Doc tests + 7 inline unit tests including u128 M_89 smoke.
Benches (criterion, M-series)
- is_prime_u64 worst case (u64::MAX − 58): 15.63 µs (3 runs ±2%)
- prev_prime_below_pow2 k=32 shard router: 7.48 ns
- next_prime_u64 ~1e9: 11.44 µs
- next_prime_u64 2^61 − 1 general path: 7.83 µs
Empirical floor finding: re-running with num-prime 0.4.4 in the same binary
on the same hardware measured num_prime::is_prime64(u64::MAX − 58) at 884 ns
vs ours at 15.63 µs — confirming the 50 ns PRD target was structurally
unachievable in safe Rust (~17.7× headroom recoverable via Montgomery in
Phase 0.1, but not 300×). PRD §6 and ADR-151 amended in a follow-up commit.
Adds the binding ADR and full PRD for the Prime-Indexed Acceleration
Layer (PIAL): a single ~250-LoC Miller-Rabin primality utility in
crates/ruvector-collections that unblocks five independent prime-aware
optimizations across hashing, sharding, sketching, and the pi-brain
witness chain.
Use cases:
* Shard-router prime modulus — closes ADR-058 finding #6
* HNSW prime-bucket adjacency — micro-hnsw-wasm, hyperbolic-hnsw
* Certified-prime LSH modulus — sparsifier, attn-mincut
* Witness-chain ephemeral primes — pi-brain brain_share payload
* Anti-aliasing prime strides — sparsifier sampler
Generation strategy combines a compile-time table of primes near 2^k
(fast path, ~1ns) with a Miller-Rabin descent fallback (~250ns). The
table is generated by build.rs from the MR implementation and
cross-checked against MR in CI, so MR remains the source of truth.
Includes HANDOFF.md with Phase 0 deliverables for the next session.
ADR and PRD pin acceptance criteria, performance targets, and a
six-phase rollout (each phase ships as a separate PR).
The Related field incorrectly referenced ADR-003 as KV Cache and
ADR-005 as LoRA Adapter Loading. In the actual repo:
- ADR-003 is SIMD Optimization Strategy
- ADR-004 is KV Cache Management (correct target)
- ADR-005 is WASM Runtime Integration (correct name)
No LoRA Adapter Loading ADR exists; ADR-005 (WASM) is the genuine
related decision for memory management concerns.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Root cause: Firestore hydration runs in background tokio::spawn but
the initial graph rebuild runs synchronously on the EMPTY memory vec
before hydration finishes. Result: 0 nodes/edges until next 6h cron.
Fix: Chain graph rebuild to the hydration task using Arc<RwLock<Graph>>.
After deploy: graph should show 1M+ edges within ~30s of startup.
Co-Authored-By: claude-flow <ruv@ruv.net>