Re-Review: Pre-settlement exit to avoid catastrophic losses
Verdict: APPROVED
Re-review of board item #1847. Previous review
review-1847-2026-07-10 returned NEEDS_REFINEMENT with 5 issues. All 5 have been resolved.Previous Issue Resolution
- [x] Wrong file path -- Fixed: issue now says
app/services/game_phase.rbwith explicit note "(note: this is in app/services/, NOT app/concerns/)" - [x] Missing blast-radius files -- Fixed:
scoreboard.rbanddashboard/index.html.erbnow in File Targets with clear change descriptions - [x] Missing include -- Fixed: first file target notes "must also
include GamePhase(currently not included, butgame_nearly_over?is needed from that module)" - [x] Non-testable AC -- Fixed: old AC4 (outcome metric "settlement loss rate drops to near zero") replaced with two verifiable ACs: scoreboard counting and dashboard styling
- [x] Traceability notes -- Fixed:
project-botfireuser-stories section exists withstory:bot-strategyentry;arch-botsnote exists (Architecture: BotFire Bot Engine, status=active)
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Discovered during Spike #11
- [x] Repo -- ldraney/botfire
- [x] User Story -- As a bot operator / I want / So that
- [x] Context -- Detailed settlement loss data ($2.97 catastrophic loss, TP $0.59 vs settlement win $0.33)
- [x] File Targets -- 4 modify + 1 do-not-touch, all verified against codebase
- [x] Feature Flag -- none
- [x] Acceptance Criteria -- 5 verifiable criteria
- [x] Test Expectations -- 3 unit tests + run command
- [x] Constraints -- 5 constraints including include requirement and downstream consumer note
- [x] Checklist -- present
- [x] Related -- present
Traceability
- [x] story:bot-strategy label -- present on board item
- [x] story note verified -- project-botfire user-stories section contains bot-strategy entry
- [x] arch:bots label -- present on board item
- [x] arch note verified -- arch-bots note exists in pal-e-docs (Architecture: BotFire Bot Engine, covers 7 services, key files, order pattern, data model, infrastructure)
- [x] Forgejo issue -- ldraney/botfire#13, open
File Targets
- [x]
app/services/position_monitor.rb-- verified: exists, has evaluate_exit (line 48) and resolve_settlement (line 69). Does NOT currently include GamePhase. Correct target for pre-settlement exit check. - [x]
app/services/game_phase.rb-- verified: exists atapp/services/(noapp/concerns/directory in project). Hasgame_nearly_over?method. Correct path. - [x]
app/services/scoreboard.rb-- verified: lines 35-36 only countstop_lossandtake_profit. New exit reason would be invisible in stats. Correct target. - [x]
app/views/dashboard/index.html.erb-- verified: line 592 hasisWin = f.exit_reason?.includes('win') || f.exit_reason?.includes('take'). A profitablepre_settlement_exitwould show as loss pill. Correct target. - [x]
app/services/bot_engine.rb-- verified: exists. Correctly listed as do-not-touch (entry logic separate from exit logic).
Repo Placement
OK -- All affected files in ldraney/botfire. Issue filed on ldraney/botfire. Single-repo change.
Dependencies
- Spawned from Spike #11 (board item #1845, ldraney/botfire#11) -- in QA column, upstream work complete.
- Sibling items from same spike: #1846 (botfire#12, backlog), #1848 (botfire#14, backlog) -- no blocking dependency.
- Item #1843 (botfire#8, "Add game phase tracking to BotFire records") -- could overlap on game_phase.rb but this ticket only consumes existing
game_nearly_over?, no conflict. - PositionMonitor must
include GamePhase-- documented in issue File Targets.
Acceptance Criteria
All 5 ACs are agent-verifiable:
- AC1: "Position monitor detects games approaching final settlement" -- testable via unit test with game_nearly_over? returning true
- AC2: "Open positions in near-settlement games are exited at market price" -- testable via unit test
- AC3: "Exit logged with exit_reason: 'pre_settlement_exit'" -- testable via assertion on BotFire record
- AC4: "Scoreboard correctly counts pre_settlement_exit in win/loss stats based on P&L sign" -- testable
- AC5: "Dashboard renders pre_settlement_exit with correct win/loss styling based on P&L" -- testable via DOM assertion
Blast Radius
- dashboard/index.html.erb line 326 -- Exit breakdown table has same
isWin = reason.includes('win') || reason.includes('take')pattern. Not explicitly called out in issue, but the constraint "All downstream consumers of exit_reason must handle the new value" covers it, and an agent grepping for exit_reason will find both locations. - dashboard_controller.rb lines 87-90 -- Computes avg_sl/avg_tp only for stop_loss/take_profit. Pre-settlement exits are a distinct category and correctly excluded from SL/TP averages. No change needed.
- volatility_bot.rb -- Has own exit logic but currently disabled. Not affected.
- volatility_bot_test.rb -- Tests check take_profit, stop_loss, time_stop exit reasons. New exit reason doesn't affect existing tests.
Decomposition Assessment
4 file targets in 1 repo, 5 ACs. All changes tightly coupled (add exit path + update downstream consumers of exit_reason). Estimated agent work: under 5 minutes. No decomposition needed.
Recommendation
No action needed. Scope is solid, all previous issues resolved, traceability triangle complete.