docs: Update Bug #82 status - comprehensive fix deployed with verification

This commit is contained in:
mindesbunister
2025-12-10 12:03:01 +01:00
parent 9e78761648
commit 0a45279c64

View File

@@ -3811,43 +3811,71 @@ This section contains the **TOP 10 MOST CRITICAL** pitfalls that every AI agent
* DB records show exit times 150-1064 minutes ago = way too old to be same position * DB records show exit times 150-1064 minutes ago = way too old to be same position
* Verifier doesn't check: Is this position newer than DB exit time? * Verifier doesn't check: Is this position newer than DB exit time?
- **THE EMERGENCY FIX (Dec 10, 2025 11:06 CET - DEPLOYED):** - **THE EMERGENCY FIX (Dec 10, 2025 11:06 CET - DEPLOYED):**
* Disabled automatic retry close completely
* Protected active positions from false closure
* Git commit: e5714e4
- **THE COMPREHENSIVE FIX (✅ DEPLOYED Dec 10, 2025 11:25 CET):**
```typescript ```typescript
// In lib/monitoring/drift-state-verifier.ts lines 276-298 // In lib/monitoring/drift-state-verifier.ts
// BUG #82 FIX: DISABLE automatic retry close // COMPREHENSIVE 6-STEP VERIFICATION PROCESS:
console.warn(`⚠️ BUG #82 SAFETY: Automatic retry close DISABLED`)
console.warn(` Would have closed ${mismatch.symbol} with 15.45 tokens`)
console.warn(` But can't verify if it's OLD position or NEW active trade`)
console.warn(` Manual intervention required if true orphan detected`)
return // Skip automatic close
// ORIGINAL CODE (COMMENTED OUT): async retryClose(mismatch) {
// const result = await closePosition({ // STEP 1: Cooldown enforcement (prevents retry spam)
// symbol: mismatch.symbol, const cooldown = await this.checkCooldown(mismatch.dbTradeId, mismatch.symbol)
// percentToClose: 100, if (!cooldown.canRetry) { return }
// slippageTolerance: 0.05
// }) // STEP 2: Load full trade context from database
``` const trade = await prisma.trade.findUnique({ where: { id: mismatch.dbTradeId } })
- **Why DISABLE vs FIX:**
* User's positions are at risk RIGHT NOW // STEP 3: Verify Drift position still exists
* Can't safely distinguish old vs new positions without proper verification const driftPosition = await driftService.getPosition(marketIndex)
* Safer to disable completely than risk more active trades being closed
* Proper fix requires position creation time check + position ID matching // STEP 4: CRITICAL - verifyPositionIdentity() runs 6 safety checks:
- **Long-Term Fix Design (TODO):** const verification = await this.verifyPositionIdentity(trade, driftPosition, currentPrice)
```typescript
// Add position verification BEFORE calling closePosition(): if (!verification.isOldGhost) {
// 1. Query Drift position creation timestamp // PROTECTED: Log skip reason and return
// 2. Compare to DB exit timestamp await this.logProtectedPosition(trade, driftPosition, verification)
// 3. If Drift position NEWER than DB exit → NEW position, DON'T TOUCH return
// 4. If Drift position OLDER than DB exit → old ghost, retry close OK }
// 5. Add position ID matching if available from Drift SDK
// 6. Add cooldown per TRADE_ID (not just symbol) // STEP 5: All checks passed → proceed with close + full logging
const result = await closePosition({ symbol, percentToClose: 100 })
await this.updateCooldown(trade.id, trade.symbol)
}
``` ```
- **Verification Logic - verifyPositionIdentity():**
* **Grace Period:** 10-minute wait after DB exit (allows Drift state propagation)
* **Direction Match:** Drift position side must match DB direction (long/short)
* **Size Match:** Position size within 85-115% tolerance (allows partial fills, funding impacts)
* **Entry Price Match:** Drift entry price within 2% of DB entry price (large difference = new position)
* **Newer Trade Detection:** Query database for trades created after exitTime (confirms new position exists)
* **Cooldown:** 5-minute per-symbol retry prevention (in-memory + database backup)
- **Safety Guarantees:**
* Fail-open bias: When uncertain → skip and alert
* Protection logging: All skipped closes recorded in database with full details
* Comprehensive decision logs: Every verification result logged with evidence
* No false closes: Multiple independent verification methods must all agree
- **Test Coverage (420 lines):**
* CRITICAL: Active Position Protection (5 tests)
- Should NOT close when newer trade exists
- Should NOT close when entry price differs >2%
- Should NOT close when size differs >15%
- Should NOT close when direction differs
- Should NOT close within 10-minute grace period
* CRITICAL: Verified Ghost Closure (2 tests)
- Should close when all verification checks pass
- Should enforce 5-minute cooldown between attempts
* CRITICAL: Edge Case Handling (4 tests)
* CRITICAL: Fail-Open Bias (1 test)
- **Files Changed:** - **Files Changed:**
* lib/monitoring/drift-state-verifier.ts (Lines 276-298 - disabled automatic close) * lib/monitoring/drift-state-verifier.ts (276 lines added - comprehensive verification)
- **Git commit:** e5714e4 "critical: Bug #82 EMERGENCY FIX - Disable Drift State Verifier automatic close" (Dec 10, 2025) * tests/integration/drift-state-verifier/position-verification.test.ts (420 lines - full test coverage)
- **Deployment:** Dec 10, 2025 11:06 CET (container trading-bot-v4) - **Git commits:**
- **Status:** ✅ EMERGENCY FIX DEPLOYED - Automatic close disabled, active positions now protected * e5714e4 "critical: Bug #82 EMERGENCY FIX" (Dec 10, 11:06 CET)
- **Next Steps:** Add proper position verification logic to safely re-enable automatic orphan cleanup * 9e78761 "critical: Bug #82 LONG-TERM FIX" (Dec 10, 11:25 CET)
- **Deployment:** Dec 10, 2025 11:25 CET (container trading-bot-v4)
- **Status:** ✅ COMPREHENSIVE FIX DEPLOYED - Intelligent verification active, automatic orphan cleanup RE-ENABLED safely
- **Red Flags Indicating This Bug:** - **Red Flags Indicating This Bug:**
* Position initially has TP/SL orders * Position initially has TP/SL orders
* Telegram alert: "X position(s) that should be closed but are still open on Drift" * Telegram alert: "X position(s) that should be closed but are still open on Drift"