learning_ai_invt_trdg/backend/REPO_AUDIT_ROADMAP.md

82 KiB

# Bytelyst Trading Platform - Holistic Engineering + Trading Audit

Date: 2026-02-15 Scope: bytelyst-trading-bot-service + bytelyst-trading-dashboard-web Method: static code review, build/lint checks, lifecycle-path trace (orders -> positions -> history)

  • Product runtime flow and execution logic:
    • docs/PRODUCT_FLOW_TRADING_LOGIC.md

Target Operating Model (Required)

  • Auto trading must execute per profile based on profile strategy rules + profile risk config.
  • Each profile must be handled identically under the same orchestration model.
  • Trade monitor must enforce stop loss / take profit correctly for each open trade.
  • Every trade lifecycle must be traceable by trade_id per profile across:
    • Active Orders
    • Open Positions
    • Trade History
  • Dashboard must stay synchronized with backend runtime state and profile configuration.

Current Validation Snapshot (2026-02-15)

  • Bot build: PASS (npm run build)
  • Dashboard typecheck: PASS (npx tsc -b)
  • Dashboard lint: PASS (npm run lint)
  • Dashboard production build: FAIL in this environment (spawn EPERM while loading vite.config.ts)
  • Bot regression suite: PASS (node --loader ts-node/esm scripts/testTradeExecutorLifecycle.ts, scripts/testLifecycleRegressions.ts, scripts/testOrderStatusSyncRegressions.ts, src/scripts/verifyWebsocketContract.ts)

Progress Snapshot (Recent)

  • Virtual profile position ledger recovery shipped (bot):
  • Profile ownership and reconciliation hardening shipped (bot):
  • Lifecycle trade-id and SL/TP fallback visibility improvements shipped (dashboard):
  • Bot-side SL/TP sync fallback + trade_id normalization shipped:
  • TP zero-guard activation fix shipped (bot):
  • Partial-exit lifecycle and OrderSync partial-fill handling shipped (bot):
  • Profile-scoped same-symbol entry parity shipped (bot):
  • Runtime risk limit enforcement shipped (maxDailyLossUsd + maxConsecutiveLosses):
  • Strategy param compatibility + entry-trigger params + AI confidence normalization shipped:
  • Strategy config schema normalization shipped (bot read-path + dashboard write/read-path):
  • Deterministic trade-id policy shipped for bot-originated lifecycle IDs:
  • Legacy trade_id backfill tooling shipped (dry-run + apply modes):
  • Lifecycle reconciliation report tooling shipped (orders -> positions -> history per profile):
  • Profile-specific symbol signal/rule aggregation shipped (bot + dashboard):
  • Dashboard lifecycle trace ledger + mismatch diagnostics shipped:
  • DB lifecycle integrity constraints + rollout plan shipped:
  • Websocket bot-state contract verifier shipped (payload shape + lifecycle consistency checks):
  • Lifecycle regression suite shipped (zero-TP guard, partial-exit reduction, stale reconciliation, order-sync stale paths):
  • CI smoke gate for dashboard production build shipped:
  • JWT issuer/audience claim hardening shipped (env-driven validation on access-token verify path):
  • Exchange/API flap failure-injection regression shipped (bot):
  • Auth threat model + executable RLS policy verification shipped:
  • Dashboard lint debt cleanup + enforced lint gate shipped:
  • Secret hygiene CI gate + rotation/history-purge runbooks shipped:
  • AI resilience shipped: fail-open AI rule + deterministic local chat fallback + AI health endpoint:

Critical Findings (P0)

  1. Take-profit guard can activate incorrectly when takeProfit is 0
  • Risk: unintended trailing-guard activation and premature exits.
  • Evidence:
    • bytelyst-trading-bot-service/src/services/tradeMonitor.ts:117
    • bytelyst-trading-bot-service/src/services/tradeMonitor.ts:118
  1. Partial exit fills are treated as full lifecycle completion
  • Risk: bot marks trade closed while residual exchange position remains open.
  • Evidence:
    • bytelyst-trading-bot-service/src/services/TradeExecutor.ts:414
    • bytelyst-trading-bot-service/src/services/TradeExecutor.ts:442
    • bytelyst-trading-bot-service/src/services/TradeExecutor.ts:461
    • bytelyst-trading-bot-service/src/index.ts:69
    • bytelyst-trading-bot-service/src/index.ts:76
  1. Per-profile identity model is still constrained by account-level symbol lock in auto-entry
  • Risk: profiles on shared account are not handled identically; second profile is blocked if net position exists for symbol.
  • Evidence:
    • bytelyst-trading-bot-service/src/services/AutoTrader.ts:110
    • bytelyst-trading-bot-service/src/services/AutoTrader.ts:112

High Findings (P1)

  1. Profile rule parameter contract mismatch for session config
  • Risk: some saved profile configs do not apply as intended.
  • Evidence:
    • bytelyst-trading-bot-service/src/strategies/rules/SessionRule.ts:18 expects params.sessions
    • default profile schemas/examples commonly use allowedSessions
  1. Entry trigger rule ignores profile parameters
  • Risk: strategy config UI implies control that runtime does not execute.
  • Evidence:
    • bytelyst-trading-bot-service/src/strategies/rules/EntryTriggerRule.ts:11
  1. AI confidence threshold scale mismatch (0-1 vs 0-100)
  • Risk: AI rule can pass too easily for some profile configs.
  • Evidence:
    • bytelyst-trading-dashboard-web/src/components/TradeProfileManager.tsx:62 (minConfidence: 0.7)
    • bytelyst-trading-bot-service/src/strategies/rules/AIAnalysisRule.ts:54 (compares against 0-100 confidence)
  1. AI prompt hardcodes BTC/USD in generic rule
  • Risk: reduced quality for non-BTC symbols.
  • Evidence:
    • bytelyst-trading-bot-service/src/strategies/rules/AIAnalysisRule.ts:83
  1. Risk limits from profile config are only partially enforced
  • Risk: maxDailyLossUsd and maxConsecutiveLosses are configured but not enforced in execution path.
  • Evidence:
    • configured in UI/schema but no enforcement path in AutoTrader / runtime guards except max open trades.
    • bytelyst-trading-bot-service/src/services/AutoTrader.ts:94
  1. Mixed-side virtual ledger collapses to dominant side
  • Risk: hidden state inconsistency when both sides exist due data anomalies.
  • Evidence:
    • bytelyst-trading-bot-service/src/services/SupabaseService.ts:610
  1. Symbol-level dashboard signal shows first profile result only
  • Risk: dashboard can misrepresent profile-specific strategy states.
  • Evidence:
    • bytelyst-trading-bot-service/src/index.ts:382
    • bytelyst-trading-bot-service/src/index.ts:400
    • bytelyst-trading-bot-service/src/index.ts:444

Medium Findings (P2)

  1. Dashboard quality gate still failing (43 lint errors, 5 warnings)
  • Risk: reduced maintainability and higher regression probability.
  1. Bot package test command still not wired
  • Risk: script-based regression suite exists, but npm test is still not standardized.
  • Evidence:
    • bytelyst-trading-bot-service/package.json ("test": "echo \"Error: no test specified\" && exit 1")
  1. Vite build environment instability (spawn EPERM)
  • Risk: release pipeline confidence gap for frontend bundle.
  1. Remaining type hygiene issues (any, @ts-ignore)
  • Risk: unsafe refactors and runtime regressions.
  • Evidence:
    • bytelyst-trading-dashboard-web/src/tabs/EntriesTab.tsx:82

Security and Compliance Residuals

  • Rotate credentials and enforce secret hygiene policy.
    • Secret hygiene enforcement + rotation runbook shipped:
  • Purge secret-bearing history before production release.
  • Add explicit RLS policy test suite for core tables.

Phased Remediation Roadmap

Phase 0 - Lifecycle Safety Hotfixes (Immediate)

  • Guard TP logic with explicit positive threshold check before target evaluation.
  • Treat partially_filled exits as partial reduction, not full trade finalization.
  • Update order-sync callback to avoid full finalize on partial exits.
  • Add regression tests for: zero-TP position, partial exit fill, stale reconciliation.
  • Normalize trade-id payload propagation (trade_id / tradeId) across bot/dashboard.

Phase 1 - Per-Profile Strategy and Risk Parity

  • Replace account-level symbol pre-check with profile-aware exposure policy (virtual sub-positioning model).
  • Enforce maxDailyLossUsd and maxConsecutiveLosses in runtime guard path.
  • Unify and validate rule param schema (sessions vs allowedSessions, confidence units).
  • Implement profile parameter support in EntryTriggerRule.
  • Add strict schema validation for strategy_config at write/read time.
  • Add profile-level execution direction control (entryMode: both | long_only) and enforce long-only entry guard.

Phase 2 - Trade Lifecycle Determinism

  • Require deterministic trade_id generation for all bot-originated orders.
  • Add DB constraint strategy and migration plan for lifecycle integrity (profile_id + trade_id indexing, null handling policy).
  • Add deterministic backfill tool for legacy rows missing trade_id.
  • Add lifecycle reconciliation report (orders -> positions -> history) per profile.

Phase 3 - Dashboard/Backend Synchronization

  • Render profile-specific signal/rule state (remove first-profile shortcut for shared symbols).
  • Add lifecycle trace view grouping by trade_id with explicit ENTRY/EXIT chain.
  • Show mismatch diagnostics when position exists without matching entry order.
  • Add websocket contract tests for payload shape and lifecycle consistency.

Phase 4 - Quality Gates and Reliability

  • Burn down dashboard lint debt to zero and enforce in CI.
  • Add bot unit/integration tests (TradeExecutor, TradeMonitor, OrderStatusSyncService, profile fan-out).
  • Add smoke tests for dashboard runtime build in CI environment matching deployment.
  • Add failure-injection tests for exchange/API flaps and stale orders.
  • Add AI degradation controls and observability (AI_FAIL_OPEN, /api/ai/health, chat local fallback).

Phase 5 - Security Hardening

  • Complete key rotation and remove plaintext secrets from tracked artifacts.
  • Execute repo history purge plan before production cut.
  • Harden JWT validation policy (issuer/audience checks) and formalize auth threat model.

Prioritized Task List (Execution Order)

Trading Correctness First

  • P0.1 TP zero-guard bug fix + tests
  • P0.2 Partial-fill lifecycle correctness fix + tests
  • P0.3 OrderSync partial-fill handling fix

Profile Parity

  • P1.1 Remove account-level symbol lock behavior for profile-isolated strategy flow
  • P1.2 Enforce profile riskLimits (maxDailyLossUsd, maxConsecutiveLosses)
  • P1.3 Normalize strategy param contract and validation
  • P1.4 Add profile-level long-only entry mode (strategy_config.execution.entryMode)

Lifecycle Traceability

Platform Quality

Definition of Done (Release Gate)

  • Every profile executes strategy/risk deterministically under the same runtime model.
  • SL/TP monitoring behaves correctly for BUY/SELL and zero-risk-field edge cases.
  • Partial fills (entry and exit) are represented accurately in orders, positions, and history.
  • Every active order, open position, and history row is traceable via a deterministic trade_id.
  • Dashboard state is consistent with backend reconciliation without profile leakage.
  • Build/type/lint/test gates pass in CI.
  • Security residuals (secrets/RLS/auth hardening) are closed for production release.

Appended Questions (Non-Blocking)

  • Should multi-profile on the same broker account support simultaneous same-symbol exposure (virtual sub-positions), or enforce one-symbol-per-account policy?
    Decision: Implemented virtual sub-positions simultaneous same-symbol exposure.
  • For partial exit fills, do you want immediate quantity reduction with continued monitoring, or full close retry loop before state mutation?
    Decision: Implemented immediate quantity reduction with continued monitoring.
  • Do you want strict rejection of profile configs that use legacy param keys (allowedSessions, confidence in 0-1), or auto-migration on read?
    Decision: Implemented auto-migration/compatibility on runtime read path.

Incremental Fix Log (2026-02-15)

  • Overview win-rate window controls shipped (24H/7D/30D/All) with profile-scoped and global win-rate metrics in selected time range.

  • Overview UX refinement shipped: removed P&L Capital Used from status bar to avoid user confusion; kept P&L Duration for contextual clarity.

  • Overview P&L context extension shipped (P&L duration window + P&L capital used with realized/open breakdown next to Net P&L):

  • Unified P&L ledger parity shipped across Overview, Audit Logs, and Strategy Clusters (single deduped history aggregation path + realized-vs-net labeling clarity):

  • Overview/History P&L parity fix shipped (Overview now uses the same merged + exact-event deduped lifecycle ledger as Audit Logs for realized and per-profile net P&L):

  • Audit Logs (History tab) integrity fix shipped (exact-event dedupe key prevents partial-exit row collapse by shared trade_id; safer timestamp and side normalization):

  • Pending EXIT ghost-order lifecycle fix shipped (serialized order-write path + stale pending_new EXIT auto-resolution when lifecycle is already closed):

  • Lifecycle trace dashboard hardening shipped (profile+trade scoped grouping, deterministic ENTRY/EXIT inference, stale-status merge guards, trace-level entry capital used, explicit state reasons):

  • Order sync not-found exception reconciliation shipped (stale pending_new orders with closed trade_id lifecycle are auto-resolved to canceled, including legacy rows without action):

  • Dashboard capital/overview accuracy update shipped (numeric-safe realized/net P&L aggregation, per-profile win rate + net P&L in Capital Scope, runtime profile state labeling):

  • Overview runtime-state UX clarity shipped for zero-utilization running profiles (monitoring vs signal-active-waiting-entry vs cooldown vs in-position):

  • Bot trade_history source-column fallback hardening shipped (legacy-schema safe insert path):

  • Manual entry capital guard shipped (scale-to-remaining capital with wait-for-release behavior):

  • Dashboard capital panel baseline shipped (allocated/used/remaining profile breakdown):

  • Dashboard history lifecycle cleanup, capital-used, and loss-highlighting shipped:

  • Trade lifecycle parity hardening shipped (legacy action=null ENTRY fallback + canonical history reconciliation tool + targeted live chain cleanup):

  • Reconciliation report signal cleanup shipped (formula mismatch diagnostics now ignore quarantined lifecycle rows already neutralized for audit safety):

  • Alpaca reconciliation carry-in baseline shipped (paged Alpaca fetch, pre-window position bootstrap, flat-vs-carry dual metrics, auto primary-mode fallback when Supabase pre-window coverage is insufficient):

Incremental Fix Log (2026-02-16)

  • Profile-symbol scoped runtime sync hardening shipped (bootstrap sync, profile hot-reload resync, reconcile loop symbol scope, dynamic monitored-symbol loop wiring):
    • bytelyst-trading-bot-service/src/index.ts
  • Legacy virtual-position reconstruction hardened for rows missing both action and trade_id (deterministic ENTRY/EXIT inference + synthetic trade-id handling):
    • bytelyst-trading-bot-service/src/services/SupabaseService.ts
  • Dedicated-profile symbol mismatch recovery hardened (USD/USDT candidate lookup for virtual-position sync):
    • bytelyst-trading-bot-service/src/services/TradeExecutor.ts
  • Stale pending_new EXIT cleanup hardened for legacy rows without trade_id (profile+symbol virtual lifecycle flat check -> auto-cancel):
    • bytelyst-trading-bot-service/src/services/OrderStatusSyncService.ts
    • bytelyst-trading-bot-service/scripts/testOrderStatusSyncRegressions.ts
  • Startup pending-order recovery hardened to auto-resolve closed EXIT-like stale rows before dashboard broadcast:
    • bytelyst-trading-bot-service/src/services/TradeExecutor.ts
  • Position merge architecture hardened to preserve stable per-trade lifecycle visibility (owner+profile+trade keyed merge instead of collapsing all same-symbol positions):
    • bytelyst-trading-bot-service/src/services/apiServer.ts
  • Profile symbol parsing hardened for array/string compatibility in entry gating:
    • bytelyst-trading-bot-service/src/services/AutoTrader.ts

Coverage Status (2026-02-16)

  • Bot service (npm run coverage:full):
    • Statements: 24.65% (1875/7606)
    • Branches: 41.20% (178/432)
    • Functions: 35.66% (56/157)
    • Lines: 24.65% (1875/7606)
  • Dashboard (npm run coverage:full):
    • Statements: 5.65% (106/1874)
    • Branches: 6.09% (128/2101)
    • Functions: 3.35% (16/477)
    • Lines: 5.48% (93/1697)

Open Enterprise Gaps (Pending)

  • True same-profile same-symbol concurrent trade support is still structurally limited by TradeExecutor in-memory Map<symbol, PositionState>.
    • Impact: multiple active lifecycles on one symbol inside one profile cannot be represented independently in runtime state.
  • Coverage is still far from 100% in both repos; current suites are regression-focused, not exhaustive component/service coverage.
  • Live Alpaca-vs-Supabase reconciliation is still script-driven, not continuously enforced as a scheduled runtime guard.
  • Legacy data quality can still introduce ambiguous lifecycle chains until historical rows are fully backfilled (trade_id, action) and constrained at DB level.

2026-02-16 Commit References

  • Lifecycle/profile sync hardening implementation batch:
  • Roadmap + product-flow documentation update:

Gap Closure Update (2026-02-16, Cycle 2)

  • Same-profile same-symbol concurrent lifecycle support implemented in runtime state model.

    • TradeExecutor now stores active positions by trade identity (symbol + trade_id) instead of one-position-per-symbol collapse.
    • AutoTrader can manage/exit multiple active lifecycles per symbol and supports controlled pyramiding (strategy_config.execution.allowPyramiding, default enabled).
    • TradeMonitor now enforces SL/TP/trailing and exchange-missing finalization per trade lifecycle (trade_id aware).
  • Runtime parity guard implemented (continuous scheduled check, not script-only).

    • Reconciliation loop now compares recent profile orders against exchange order statuses and auto-corrects safe terminal mismatches.
    • Runtime health now tracks parityMismatchCount.
  • Legacy lifecycle recovery further hardened for per-trade reconstruction.

    • Added profile/symbol/trade_id scoped virtual open-position reconstruction (getVirtualOpenPositionForTrade).
    • Dedicated profile sync now reconstructs multiple open slices per symbol when multiple trade_ids remain open.
  • Manual square-off updated to close all active sub-positions for a symbol (trade_id aware), not just one selected row.

  • Coverage remains below enterprise target.

    • Bot (npm run coverage:full): Statements 24.60%, Branches 41.72%, Functions 36.09%, Lines 24.60%.
    • Dashboard (npm run coverage:full): Statements 5.65%, Branches 6.09%, Functions 3.35%, Lines 5.48%.

Residual Open Gap

  • Expand automated tests toward enterprise target coverage (module-level + integration-level) across both repos.
  • Multi-lifecycle runtime + parity guard implementation:

Gap Closure Update (2026-02-16, Cycle 3)

  • Fixed dedicated-profile sync gap that could drop valid local lifecycle positions when exchange remained open but virtual reconstruction was temporarily empty.

    • TradeExecutor.syncPositions now retains existing local symbol lifecycles when exchange position exists and virtual lookup returns empty.
    • Local symbol state is only cleared when exchange is flat and no virtual lifecycle remains.
  • Improved dashboard state freshness for lifecycle transitions.

    • TradeExecutor.openPosition now pushes updated active positions immediately after confirmed entry fill.
    • TradeExecutor.finalizeTrade now pushes updated active positions immediately after local lifecycle removal.
  • Added regression coverage for the above lifecycle-sync protections.

    • Extended scripts/testTradeExecutorLifecycle.ts to assert:
      • immediate position snapshot propagation after filled entry
      • local lifecycle retention on exchange-open plus virtual-empty sync window

Residual Open Gap

  • Coverage remains below enterprise target across full repository scope.
  • Lifecycle retention plus immediate position push plus regression tests:

Gap Closure Update (2026-02-16, Cycle 4)

  • Hardened order persistence to be idempotent on order_id so duplicate lifecycle rows are not inserted on retries.

    • Existing order rows are merged/updated, and terminal statuses are not downgraded by late pending writes.
  • Hardened stale-order detection and reconciliation cadence to reduce stale pending_new artifacts.

    • Added configurable runtime controls: ORDER_SYNC_INTERVAL_MS, STALE_ORDER_THRESHOLD_MINUTES.
    • Expanded stale-pending scope to include pending_new, pending, accepted, and new.
  • Added regression guardrail for order persistence and stale status scope.

    • New suite: scripts/testSupabaseOrderPersistenceRegressions.ts.
    • Included in regression/coverage execution paths.
  • Dashboard lifecycle table hardening shipped.

    • Bot positions are deduped by profile_id plus trade_id before rendering.
    • Pending EXIT rows are normalized to closed when lifecycle is already closed in history for the same trade_id scope.
  • Coverage progress (full-scope baseline run on 2026-02-16).

    • Bot (npm run coverage:full): Statements 28.29%, Branches 40.59%, Functions 41.04%, Lines 28.29%.
    • Dashboard (npm run coverage:full): Statements 5.58%, Branches 5.98%, Functions 3.34%, Lines 5.40%.

Residual Open Gap

  • Full enterprise target coverage is still pending; broad module/component test expansion is still required across both repos.
  • Bot lifecycle dedupe plus stale sync cadence plus persistence regression:
  • Dashboard lifecycle table stabilization:

Gap Closure Update (2026-02-16, Cycle 5)

  • Expanded dashboard enterprise coverage across tabs/components/hooks with deterministic runtime-safe tests.
    • Added coverage suites for:
      • App
      • OverviewTab, PositionsTab, SignalsTab, EntriesTab, SettingsTab, AdminTab, HistoryTab, ConfigTab
      • AuthContext, TradeProfileManager config normalization, PriceChart, AlertFeed, MarketTicker, market-opportunity widgets, EntryForm, SymbolCard
      • useWebSocket, supabaseClient, const module
  • Added deterministic lifecycle-branch assertions in dashboard tab coverage:
    • Lifecycle states: OPEN, PARTIAL_EXIT, CLOSED, ORPHAN_EXIT, EXIT_PENDING
    • Stale pending-order banner behavior and mismatch diagnostics rendering
  • Kept strategy-config normalization logic testable by exporting normalizeStrategyConfig and validating legacy compatibility paths.
  • Re-ran quality gates for both repos after coverage expansion:
    • Dashboard: npm run check -> PASS
    • Dashboard: npm run coverage:full -> PASS
    • Bot: npm run check -> PASS
    • Bot: npm run coverage:full -> PASS

Coverage Status (2026-02-16, Post Cycle 5)

  • Bot service (npm run coverage:full):
    • Statements: 28.19% (2278/8080)
    • Branches: 40.73% (233/572)
    • Functions: 40.46% (70/173)
    • Lines: 28.19% (2278/8080)
  • Dashboard (npm run coverage:full):
    • Statements: 42.46% (806/1898)
    • Branches: 34.71% (743/2140)
    • Functions: 33.26% (159/478)
    • Lines: 44.25% (762/1722)

Residual Open Gap

  • Enterprise coverage target is not yet complete for both repos; remaining work is deeper branch-path and service-level integration coverage expansion.
  • Existing workspace still contains unrelated pending file changes; only targeted coverage/test files were committed in this cycle.

Coverage Status (2026-02-16, Latest Refresh)

  • Re-ran broad coverage snapshots (npm run coverage:full) for both repos and updated the dedicated report:
    • docs/COVERAGE_BEFORE_AFTER_2026-02-16.md
  • Re-ran enforced 80% gate coverage (npm run coverage) for both repos.

Broad Coverage (Latest)

  • Bot service (npm run coverage:full):
    • Statements: 55.68% (4499/8080)
    • Branches: 55.76% (629/1128)
    • Functions: 64.51% (160/248)
    • Lines: 55.68% (4499/8080)
  • Dashboard (npm run coverage:full):
    • Statements: 90.53% (1760/1944)
    • Branches: 75.61% (1619/2141)
    • Functions: 88.24% (443/502)
    • Lines: 92.11% (1624/1763)

Gate Coverage (Latest)

  • Bot service (npm run coverage):
    • Statements: 97.87% (92/94)
    • Branches: 93.02% (40/43)
    • Functions: 92.30% (12/13)
    • Lines: 97.87% (92/94)
  • Dashboard (npm run coverage):
    • Statements: 99.06% (106/107)
    • Branches: 94.16% (129/137)
    • Functions: 100% (16/16)
    • Lines: 98.93% (93/94)

Focus Coverage

  • Dashboard PositionsTab (src/tabs/PositionsTab.tsx):
    • Statements: 98.61% (498/505)
    • Branches: 78.86% (500/634)
    • Functions: 100% (112/112)
    • Lines: 100% (459/459)

Gap Closure Update (2026-02-16, Cycle 6)

  • Fixed runtime duplicate position/order artifacts by introducing canonical snapshot merge logic in backend state updates.
    • Positions are merged by stable trade_id first; fallback merges are owner+symbol+side scoped.
    • Orders are merged by order_id with terminal-status precedence to prevent stale status downgrade.
  • Fixed lifecycle linkage and aggregate math drift in dashboard history/overview.
    • Trade-history aggregation now runs by lifecycle (profile_id + trade_id) instead of raw row count.
    • Duplicate lifecycle events with reason formatting differences are normalized and collapsed.
    • Win rate and realized P&L now reflect lifecycle outcomes, not duplicated sync rows.
  • Fixed profile/trade distinction drift in open positions view.
    • Runtime position dedupe now prefers trade_id keyed identity and preserves richer profile metadata.
    • Overview capital utilization and unrealized P&L now compute from deduped runtime positions.
  • Added/updated regression coverage for merge and lifecycle aggregation paths.
  • Re-ran quality gates and coverage baselines across both repos after fixes.

Coverage Status (Cycle 6 Snapshot)

  • Full scope (npm run coverage:full):
    • Bot service: Statements 57.05% (4738/8304), Branches 55.24% (685/1240), Functions 66.53% (175/263), Lines 57.05% (4738/8304)
    • Dashboard: Statements 90.72% (1809/1994), Branches 75.40% (1662/2204), Functions 88.38% (449/508), Lines 92.37% (1673/1811)
  • Gate scope (npm run coverage):
    • Bot service: Statements 97.87%, Branches 93.02%, Functions 92.30%, Lines 97.87%
    • Dashboard: Statements 97.70%, Branches 88.75%, Functions 94.44%, Lines 100%

Root Cause (Closed)

  • Primary architecture gap was non-canonical merge and aggregation.
    • Runtime sources were merged without lifecycle-first identity guarantees.
    • Dashboard aggregate paths mixed row-level and lifecycle-level counting.
  • Primary coding bug was metadata-poor row overwrite during dedupe, which dropped profile context and inflated/fragmented position and P&L views.

Remaining Enterprise Gaps

  • 100% full-repo coverage target is not yet reached; current full-scope coverage is materially improved but not complete.
  • Add continuous reconciliation alerting for lifecycle chain anomalies (orphan_exit, unclassified) at API and UI health surfaces.
  • Bot runtime merge hardening + regression suite:
  • Dashboard lifecycle aggregation + runtime dedupe hardening: