Review: Bug: Scanner never attaches markets to basketball games
Verdict: NEEDS_REFINEMENT
Board item #1850 —
ldraney/botfire#19. Bug type issue. The scope is well-written and the bug is confirmed in code, but the traceability triangle is incomplete: the arch-bots architecture note referenced by the arch:bots label does not exist in pal-e-docs.Template Completeness
- [x] Type — Bug
- [x] Lineage — references spike #18
- [x] Repo —
ldraney/botfire - [x] What Broke — detailed explanation of the skip-existing-games bug
- [x] Repro Steps — 5 concrete steps with Rails console commands
- [x] Expected Behavior — clear description of retry behavior
- [x] Environment — Docker Compose on archbox, scanner service path
- [x] Acceptance Criteria — 4 testable criteria
- [x] Related — links to project-botfire and spike #18
Traceability
- [x] story:bot-strategy label — present on board item
- [x] story note verified — found in project-botfire user-stories section: "As a bot operator, I want to identify and exploit profitable trading conditions..."
- [x] arch:bots label — present on board item
- [ ] arch note MISSING — [SCOPE] Create architecture note
arch-botsfor component bots. Search for "arch-bots" returned 0 results. - [x] Forgejo issue — ldraney/botfire#19, state: open
File Targets
- [x]
app/services/scanner.rb— verified: file exists (258 lines) - [x]
discover_gamesmethod — verified: defined at line 45 - [x]
Game.exists?(milestone_id: m["id"])— verified: line 53, this is the root cause. Games that already exist are rejected fromnew_milestones, so their market discovery is never retried. - [x]
real_game_market?filter — verified: line 116-122, checks for/GAME/in ticker.KXWNBAGAME-*tickers would pass this filter correctly.
Repo Placement
OK. Issue filed on
ldraney/botfire, fix is in app/services/scanner.rb in the same repo. Single-repo fix.Dependencies
- No blocking dependencies. Item is in backlog with no items it depends on.
- Downstream: item #1851 (Per-sport analytics: track Live Edge performance by sport type) would benefit from this fix, as it needs basketball market data to track per-sport performance. Not a blocker.
- Item #1848 (Tighten Live Edge ceiling) is in QA but is independent — it adjusts price thresholds, not sport type discovery.
Acceptance Criteria
4 criteria, all machine-verifiable:
- [x] AC1: Basketball game-winner markets attached — testable via
Market.joins(:game).where(games: { sport_type: "basketball_game" }).count - [x] AC2: Scanner retries for games with 0 markets — testable by observing scanner logs after restart
- [x] AC3: No regression in baseball discovery — testable by checking baseball market counts before/after
- [x] AC4: Market count > 0 after scanner runs — directly testable Rails console query
All criteria are concrete and agent-verifiable. No missing criteria detected.
Blast Radius
- The
reject { |m| Game.exists? }pattern exists only inscanner.rbline 53 — no sibling services share this pattern. - Downstream:
bot_engine.rbqueriesMarket.where(status: "active").joins(:game).where(games: { sport_type: sport_types })(line 78-81). Once basketball markets appear, bots configured to watchbasketball_gamewill start evaluating those markets. This is expected/desired behavior. volatility_bot.rbincludesbasketball_gameinHEDGEABLE_SPORTS(line 13) — but the volatility bot is currently disabled per board item #1840.- The
game_phase.rbservice already handlesbasketball_gamesport type (line 10, 32) — no changes needed there.
Decomposition Assessment
No decomposition needed. 1 primary file target (
scanner.rb), 4 acceptance criteria, estimated under 5 minutes of agent work. Well within the single-pass threshold.Recommendation
[SCOPE]Create architecture notearch-botsfor the bots component. All 12 board items on board-bots carry thearch:botslabel but no backing architecture note exists. This should document the scanner, bot_engine, and bot service architecture.