jgrusewski 980f3b07f3 diag(policy-quality): Task 2.0 extension — instrument 5 more grad writers
First Task 2.0 pass (commit d60e5375a) covered IQN/CQL/C51/Ens. Result:
IQN+Ens are architecturally zero (don't touch branches); C51+CQL send
30-400× more gradient to magnitude than direction. But Task 0.4's
grad_ratio_mag_dir=0.0000 at epoch end — so magnitude gradient gets
cancelled somewhere in the aux-graph gap between CQL/C51 and epoch end.

This commit instruments the 5 unmeasured writers/scalings:
  - apply_distillation_gradient
  - launch_recursive_confidence_backward
  - compute_predictive_coding_loss
  - apply_c51_budget_scale (multiplicative; signed delta reveals shrinkage)
  - apply_cql_saxpy (multiplicative)

Schema extended 4 → 9 components. Pinned result slot grew 8 → 18 floats.
9 device scratch buffers (~90 MB total on RTX 3050 Ti — 2.2% of 4 GB,
acceptable for diagnostic).

HEALTH_DIAG now emits:
  grad_split_bwd [iqn=… cql=… c51=… ens=…]
  grad_split_aux [distill=… rec=… pred=… cql_sx=… c51_bs=…]

No atomicAdd (block-internal tree reduction). memcpy_dtod_async is not
captureable → used graph_safe_copy_f32 (same as first pass).

Last 5 epochs (HEALTH_DIAG[15..19]), RTX 3050 Ti, magnitude_distribution
smoke test:

  grad_split_bwd [iqn=0.0000 cql=18.4618  c51=102.2001 ens=0.0000]
  grad_split_aux [distill=1.2281 rec=0.0000 pred=0.0000 cql_sx=18.4618  c51_bs=102.2001]

  grad_split_bwd [iqn=0.0000 cql=55.0089  c51=125.1374 ens=0.0000]
  grad_split_aux [distill=1.2381 rec=0.0000 pred=0.0000 cql_sx=55.0089  c51_bs=125.1374]

  grad_split_bwd [iqn=0.0000 cql=30.1931  c51=262.0410 ens=0.0000]
  grad_split_aux [distill=0.7916 rec=0.0000 pred=0.0000 cql_sx=30.1931  c51_bs=262.0410]

  grad_split_bwd [iqn=0.0000 cql=70.2364  c51=126.6637 ens=0.0000]
  grad_split_aux [distill=0.7397 rec=0.0000 pred=0.0000 cql_sx=70.2364  c51_bs=126.6637]

  grad_split_bwd [iqn=0.0000 cql=103.3925 c51=104.4165 ens=0.0000]
  grad_split_aux [distill=0.8085 rec=0.0000 pred=0.0000 cql_sx=103.3925 c51_bs=104.4165]

Keystone findings for Task 2.1:

* rec (recursive confidence) + pred (predictive coding) report 0.0000
  every epoch — architecturally expected: MSE/predictive gradients flow
  through bw_d_h_s2 / trunk tensors 0..8 only, they never touch branch
  tensors 8..16. Same architectural-zero class as IQN+Ens.

* distill is the only aux writer that actually touches branches, but at
  ratios ~0.5–1.2 (nearly balanced mag/dir), so it cannot be the source
  of Task 0.4's grad_ratio_mag_dir=0 cancellation.

* cql_sx ≡ cql and c51_bs ≡ c51 exactly (ratio, not norm). This is
  expected — multiplicative scalings (saxpy budget / c51 budget scale)
  uniformly scale BOTH direction and magnitude slices, so the mag/dir
  RATIO is invariant. These ops change amplitude, not balance.

Conclusion: NONE of the 9 instrumented stages zero the magnitude signal.
CQL+C51 reach grad_buf with huge mag/dir ratios (30-400×); distill adds
a balanced micro-contribution; rec/pred/iqn/ens/scalings all architectur-
ally neutral for the mag/dir ratio. Yet Task 0.4's post-step
grad_ratio_mag_dir=0 (meaning dir < 1e-9).

Re-reading Task 0.4's impl: `per_branch_grad_norms` returns [dir, mag, …]
and the ratio is `mag / dir if dir > 1e-9 else 0.0`. So 0.0000 means
dir_norm is zero, NOT mag cancelled. Task 0.4's measurement runs at
EPOCH boundary after Adam consumes grad_buf — which means the "cancel"
is either (a) Adam consuming/zeroing grad_buf pre-readback, (b) the
next step's `submit_forward_ops_main` memset firing before Task 0.4's
DtoH reads, or (c) something Adam-related that drops dir to zero.

Five unmeasured writers verified present (all 5 exist via grep +
read — none renamed or deleted since the first pass's report). Writers
that DON'T touch branches (rec/pred) are now explicit 0.0000 evidence,
not speculation.

Feeds Task 2.1's decision tree: H4 is NOT caused by cancellation in
the aux-graph gap. Next hypothesis: Adam grad_buf lifecycle / Task 0.4
timing relative to memset.

Build clean; magnitude_distribution smoke green (21.90 s local, RTX 3050 Ti).
Test result: 1 passed; 0 failed.

Push status: deferred — first Task 2.0 pass reported network unreachable
(d60e5375a local-only). Will attempt in same commit cycle; if it fails
again, that's consistent with the prior pass's finding.

Per plan Task 2.0 extension (from Task 2.0 first-pass escalation report).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 10:35:53 +02:00

Foxhunt

Production HFT trading system in Rust.

Architecture

The workspace contains 32 crates organized as follows:

Core Libraries (16)

Crate Purpose
trading_engine Order processing, FIX 4.4, IB TWS, SIMD, RDTSC timing
risk VaR, Kelly, circuit breakers, kill switches, compliance
risk-data Risk data types and shared structures
trading-data Trading data types
ml DQN Rainbow, PPO, TFT, Mamba2, ensemble inference
ml-data ML data types and feature definitions
data Market data ingestion and storage
backtesting Replay engine, strategy tester
adaptive-strategy Ensemble execution, microstructure analysis
common Shared types, resilience, error handling
storage S3 and local model storage
model_loader Model serialization and loading
market-data Market data feed handlers
database PostgreSQL access layer (SQLx)
config Configuration management
tli CLI commands and tooling

Services (8)

Service Purpose
backtesting_service gRPC backtesting service
broker_gateway_service FIX routing, broker connectivity
trading_service Core trading operations
ml_training_service Model training orchestration
data_acquisition_service Market data acquisition
trading_agent_service Autonomous trading agents
api_gateway gRPC API gateway with auth
web-gateway Axum REST + WebSocket gateway

Frontend

web-dashboard/ -- React 19 + TypeScript + Vite + TradingView charts.

Building

# Check compilation (no PostgreSQL required)
SQLX_OFFLINE=true cargo check --workspace

# Run tests for a specific crate
SQLX_OFFLINE=true cargo test -p <crate> --lib

# Clippy
SQLX_OFFLINE=true cargo clippy --workspace

ML Models

Four production model architectures on Candle v0.9.1 with CUDA:

  • DQN Rainbow -- Deep Q-Network with prioritized replay, dueling heads, noisy nets
  • PPO -- Proximal Policy Optimization with GAE and LSTM policies
  • TFT -- Temporal Fusion Transformer for multi-horizon forecasting
  • Mamba2 -- State space model for sequence prediction

Each model has a standalone trainer and a UnifiedTrainable adapter for the hyperopt pipeline.

Infrastructure

  • Git: Gitea at git.fxhnt.ai (Tailscale-only), Scaleway DEV1-S
  • Observability: OpenTelemetry OTLP (env OTEL_EXPORTER_OTLP_ENDPOINT)
  • Database: PostgreSQL with SQLx offline mode for CI

License

Proprietary. All rights reserved.

Description
No description provided
Readme 849 MiB
Languages
Rust 88.2%
Cuda 7.7%
Python 1.3%
Shell 1.1%
PLpgSQL 0.8%
Other 0.8%