Swap the stale trading_service monitoring proto (10 RPCs, never
implemented) for the real monitoring_service proto (2 RPCs:
GetLiveTrainingMetrics, StreamTrainingMetrics). Add a dedicated
MonitoringServiceProxy that forwards directly to monitoring-service
on port 50057, so `fxt watch` works end-to-end through the gateway.
- build.rs: compile monitoring_service/proto/monitoring.proto with server+client
- MonitoringServiceProxy: new zero-copy proxy (unary + streaming)
- TradingServiceProxy: remove monitoring_client, stub 6 stale methods
- main.rs: MONITORING_SERVICE_URL env, optional proxy with graceful degradation
- Network policies: api-gateway↔monitoring-service egress/ingress on 50057
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ml_training_service: handlers delegate to promotion_manager
- api_gateway: proxy pass-through for both new RPCs
- Proto messages added to service-side ml_training.proto
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove unnecessary async from init_observability -- body was fully sync.
Change otlp_endpoint from &str to Option<&str> -- when None, OTLP layer
is skipped (fmt-only mode). Update all 8 service callers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Create 3 missing service READMEs (api_gateway, data_acquisition_service,
trading_agent_service). Create bin/fxt/README.md. Create
testing/service-integration/README.md. Update existing service and testing
READMEs to standard template. Delete 4 subdirectory READMEs from
testing/integration/ and testing/e2e/.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove stale test reports, quick-start guides, benchmark analyses,
profiling reports, and tool artifacts from across the workspace.
Keeps only root README.md per crate/service.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add tracing::instrument(skip_all) to gRPC handlers across all services
for distributed trace spans via OTLP. Pairs with Prometheus scrape
annotations from previous commit.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace direct tracing_subscriber::fmt::init() calls with the unified
common::observability::init_observability() in api_gateway, web-gateway,
data_acquisition_service, broker_gateway_service, and trading_agent_service.
All 8 services now emit JSON logs + OTLP traces to Tempo.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Extend ml_training_service to dispatch GPU training jobs as K8s batch/v1
Jobs, collect results via a Rust sidecar uploader, and support model
promotion with operator approval via fxt CLI.
- K8s dispatcher creates Jobs on gpu-training pool with native sidecar
- training_uploader crate: watches DONE/FAILED marker, uploads to S3,
reports completion via ReportJobCompletion gRPC
- PromotionManager compares metrics, queues better models for approval
- 4 new proto RPCs: ReportJobCompletion, ListPendingPromotions,
ApprovePromotion, RejectPromotion
- fxt commands: train start, model list/approve/reject
- Training binaries write DONE/FAILED markers + metrics.json
- Dockerfile, K8s job template, and CI pipeline updated
- StartTraining gracefully falls back to in-process when outside K8s
- 27 new tests (16 service + 11 promotion), 141 total service tests pass
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move 17 library crates into crates/, CLI binary into bin/fxt,
consolidate 10 test crates into testing/, split config crate
from deployment config files.
Root directory reduced from 38+ to ~17 directories.
All Cargo.toml paths and build.rs proto refs updated.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add #![deny(clippy::unwrap_used, clippy::expect_used)] to 11 crates that
were missing it, and standardize 3 existing crates to deny both lints.
Test code is exempted via #![cfg_attr(test, allow(...))].
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Strip all 413 #[allow(dead_code)] annotations from 139 files and remove
the actual dead code they were suppressing: unused struct fields (and their
constructor sites), unused methods/functions, and entire dead structs.
Key removals:
- trading_engine compliance: ~50 dead structs/fields across audit, reporting, SOX modules
- trading_service: dead execution engine fields, broker routing, paper trading methods
- ml_training_service: dead TLS validation (~340 lines), GPU state, monitoring fields
- backtesting_service: dead model cache, TLS validation, TradeSignal fields
- risk: dead VaR engine fields, safety coordinator fields, position tracker fields
- adaptive-strategy: dead ensemble methods, regime detection, sizing functions
147 files changed, -4264 net lines. Workspace compiles with 0 errors.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Workspace tokio already specifies the needed features (rt-multi-thread,
macros, net, sync, time, fs, signal, io-util, test-util). Three crates
(test_common, test_harness, vault_integration) were skipped because
they are not workspace members and cannot use workspace = true.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
All 6 service Dockerfiles were missing newly-added workspace crates
(web-gateway, ctrader-openapi, foxhunt-deploy, broker_gateway_service),
causing cargo workspace resolution failures during Docker builds.
Changes across all Dockerfiles:
- Add COPY directives for web-gateway, ctrader-openapi, foxhunt-deploy,
broker_gateway_service (new workspace members since Dockerfiles written)
- Add SQLX_OFFLINE=true env and .sqlx cache copy where missing
- Add perl and make system deps (needed for OpenSSL build from source)
- Remove COPY migrations (dir excluded by .dockerignore, not needed)
- Expand broker_gateway_service from 3-crate to full workspace copy
Validated: docker build --check passes all 6, cargo check -p passes all 6.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tasks 8-14 production hardening batch:
- Populate Order/Position/Execution proto messages from JSON payload in event
stream converters instead of returning None (Task 9)
- Compute max_drawdown from cumulative PnL samples in A/B testing pipeline
instead of hardcoded 0.0 (Task 11)
- Document feature pipeline integration blockers with detailed roadmap
comments in state.rs and trading.rs (Task 8)
- Document realized PnL gap: TradingPosition lacks the field, repository
has async method incompatible with Iterator::map (Task 10)
- Document ML order quantity gap in api_gateway proxy: MlOrderResponse
proto lacks quantity field (Task 12)
- Document per-symbol weight tracking roadmap in ensemble_coordinator (Task 13)
- Document OHLCV bar pipeline upgrade roadmap in state.rs (Task 14)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move identical TLS type definitions from 4 service crates into
common/src/tls.rs, eliminating ~435 lines of duplicated code.
Each service retains its own TlsConfig struct and validation logic
(async vs sync, delegated vs monolithic) while sharing the type
definitions. Services re-export the types for backward compatibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove 45+ AGENT_*, WAVE_*, and completion report files that were
one-time swarm deliverables with no living documentation value.
Remove reports/2025-11-16_17_hyperopt_analysis/ (55 files, code
changes already landed). Content preserved in git history.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed error!() call that logged the full JWT token on decode failure.
This was a security risk - tokens should never appear in logs.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- api_gateway: DATABASE_URL now required (was fallback to hardcoded dev password)
- broker_gateway: DATABASE_URL now required (was fallback to hardcoded dev password)
- broker_gateway: add deny(clippy::unwrap_used, clippy::expect_used) to lib.rs
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- api_gateway/revocation.rs: 7 Prometheus .unwrap()→abort pattern
- ml_training/simple_metrics.rs: remove #![allow(clippy::unwrap_used)],
fix 4 Prometheus .unwrap()→abort pattern
All service crates now enforce deny(unwrap_used) without file-level
overrides.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- api_gateway/main.rs: 18 expect→? or match+error! (gateway crash=outage)
- broker_gateway/metrics.rs: 24 expect→unwrap_or_else+abort (startup-only)
- ml_training/training_metrics.rs: 32 unwrap→unwrap_metric helper+abort
All Prometheus metric registrations now use explicit error handling
instead of bare .unwrap()/.expect(). Production panic surface reduced
by ~75%.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
risk: replace 14 .to_string() on &str with .to_owned(), rename shadow
api_gateway: replace unwrap/expect with safe alternatives in mTLS
validator, config regex compilation, and metrics initialization
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the stub OCSP implementation with a fully functional RFC 6960
compliant revocation checker that:
- Builds OCSP requests using SHA-1 hashes of issuer name/key via the
ocsp crate's CertId and OneReq types with proper DER encoding
- Sends requests via HTTP POST with correct Content-Type headers
- Parses DER-encoded OCSP responses to extract response status
(successful/malformed/internal-error/try-later/unauthorized)
- Determines certificate status (Good/Revoked/Unknown) by locating
the serial number and scanning for ASN.1 context-specific tags
- Caches results in the existing LRU cache with TTL
- Increments Prometheus metrics for all failure paths
Add #![deny(clippy::unwrap_used, clippy::expect_used)] to api_gateway and
backtesting_service crate roots. The ml and common crates already had these
deny attributes.
Production code fixes:
- api_gateway: replace expect with unwrap_or for cache stats and LRU eviction
- api_gateway: add #[allow] on NonZeroU32 constants and Prometheus metrics
- backtesting_service: replace expect/unwrap with ok_or_else/? for OHLCV
bar bounds checks and chrono timestamp resampling
- backtesting_service: add #[allow] on Prometheus Lazy metric statics
Test code: cfg_attr(test, allow) at crate root for both crates.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the TODO placeholder with proper CRL validation that checks:
- thisUpdate is not in the future (CRL not yet valid)
- nextUpdate is not in the past (CRL expired)
- CRL issuer matches the certificate issuer (prevents CRL substitution)
All checks use x509-parser's ASN1Time for accurate time comparison
and log warnings/errors via tracing for operational visibility.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace the TODO stub in validate_certificate_chain with full
cryptographic chain-of-trust verification using x509-parser's ring-backed
verify feature:
1. Issuer CN matching -- client cert issuer must equal CA subject CN
2. CA validity period -- reject expired or not-yet-valid CA certificates
3. CA Basic Constraints -- verify the signer actually has cA=true
4. Cryptographic signature -- verify client cert TBS data signature
against the CA's SubjectPublicKeyInfo (RSA/ECDSA/Ed25519 via ring)
Also enables the "verify" feature on x509-parser and extends the method
signature to accept ca_cert_pem for proper chain validation.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- fix(trading_engine): replace Prometheus panic! with graceful registration
- fix(trading_service): implement partial fill matching in order book
- feat(trading_service): replace feature extraction stub with real 51-dim pipeline
- feat(trading_service): wire RiskEngine with real VaR calculator
- fix(api_gateway): implement real ML prediction proxy
- feat(data_acquisition): implement DBN data downloader
- feat(data): wire DBN uploader with MinIO integration
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
CRITICAL BLOCKER FIX: Tests were hanging for 60+ seconds due to invalid
Redis timeout URL parameters that are silently ignored by redis v0.27.6.
Root Cause:
- redis crate v0.27.6 does NOT support connection_timeout or response_timeout
as URL parameters
- When Redis unavailable, code blocks waiting for OS-level TCP timeout (60s+)
Solution:
- Wrap async Redis operations with tokio::time::timeout()
- Test timeouts: 2s connection, 1s operations (PING/FLUSHDB)
- Production timeout: 5s connection
Files Modified:
- services/api_gateway/tests/common/mod.rs (lines 119-211)
- Fixed wait_for_redis() with tokio timeout wrappers
- Fixed cleanup_redis() with tokio timeout wrappers
- Removed broken add_redis_timeouts() function
- services/api_gateway/src/auth/jwt/revocation.rs (lines 285-316)
- Fixed JwtRevocationService::new() with tokio timeout wrapper
Closes: JWT authentication test hang blocker
Impact: Tests now fail fast (2-5s) instead of hanging for 60+ seconds
- Add .t() transpose to all weight matrix multiplications
- Add .contiguous() after transpose to fix non-contiguous errors
- Fix causal mask using additive masking instead of where_cond
- Fix mask dtype compatibility (F32 instead of U8)
All 8 quantized_attention tests now passing.
**Problem**:
- api_gateway binary and real_backend_integration_test had compilation errors
- Missing observability module caused binary to fail compilation
- Incorrect proto imports and field access in integration tests
**Changes**:
1. services/api_gateway/src/main.rs:
- Removed call to common::observability::init_observability (module commented out in common)
- Replaced with simple tracing_subscriber::fmt::init()
- Removed unused imports (layer::SubscriberExt, util::SubscriberInitExt)
2. services/api_gateway/tests/real_backend_integration_test.rs:
- Fixed proto imports: use tli::proto::health::{HealthClient, HealthCheckRequest}
- Replaced TradingServiceClient with HealthClient (standard gRPC health check)
- Replaced BacktestingServiceClient with HealthClient
- Fixed field access: health.status -> health.healthy for ML service
- Fixed field access: health.status string -> health.status i32 (ServingStatus enum)
- Updated all 8 test functions to use correct proto types
- Pre-commit hook automatically changed .health_check() to .check() (correct method name)
**Tests Fixed**:
- api_gateway binary compilation (1 error fixed)
- real_backend_integration_test compilation (7 errors fixed)
**Impact**:
- 2 of 6 service test failures resolved
- api_gateway binary now compiles and runs
- Integration tests now use correct proto definitions
Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Wave 9: Feature Integration (20 agents)
- Wire Wave D features into extraction pipeline (ml/src/features/extraction.rs:197-204)
- Reduce statistical features from 50 to 26 to make room for Wave D
- Update method signature to &mut self for stateful extractors
- Fix 7 division-by-zero bugs in feature extraction
- Train all 4 models (DQN, PPO, MAMBA-2, TFT) with 225 features
- Test pass rate: 99.2% (2,061/2,074 tests)
Wave 10: Production Feature Extractor Fix (1 agent)
- Create ProductionFeatureExtractor225 trait
- Implement ProductionFeatureExtractorAdapter
- Fix production code using only 66 features + 159 zeros
- Use dependency injection to avoid circular dependencies
Wave 11: Service Migration (20 agents)
- Migrate Trading Service to use ProductionFeatureExtractorAdapter
- Migrate Backtesting Service to use production extractor
- Update all integration tests and E2E tests
- Performance: 3.98μs/bar (22% faster than Wave 9)
- Test pass rate: 99.84% (1,239/1,241 tests)
Key Achievements:
- All 225 features (201 Wave C + 24 Wave D) fully integrated
- All services using production feature extractor
- Zero NaN/Inf errors after division-by-zero fixes
- 922x average performance improvement vs targets
- System 100% ready for extended training data download
Files Modified:
- ml/src/features/extraction.rs (Wave D wiring)
- ml/src/features/production_adapter.rs (NEW - adapter pattern)
- common/src/ml_strategy.rs (trait + dependency injection)
- services/trading_service/src/paper_trading_executor.rs
- services/backtesting_service/src/ml_strategy_engine.rs
- 18+ test files updated for &mut self pattern
Next Steps:
- Wave 12: Download 180 days Databento data (~$3.50)
- Wave 13: Retrain all models with extended datasets
- Wave 14: Run Wave Comparison Backtest
- Wave 15-16: Production deployment
🤖 Generated with Claude Code (Waves 9-11: 41 agents, 153 total)
Co-Authored-By: Claude <noreply@anthropic.com>