Review: OrderService dry_run enforcement + budget guardrails
Verdict: APPROVED
Ticket is well-scoped, file targets verified, traceability solid. One minor arch note gap flagged as systemic (not blocking).
Template Completeness
- [x] Type — Feature
- [x] Lineage — Sub-ticket of #85, split 2 of 3
- [x] Repo — ldraney/prediction-assistant
- [x] User Story — present, well-formed
- [x] Context — explains relationship to #85, dependency on sub-ticket 1
- [x] File Targets — 2 files to modify, 2 files explicitly excluded
- [x] Feature Flag — "none" with justification (internal service change, no FF infra)
- [x] Acceptance Criteria — 7 items
- [x] Test Expectations — 5 unit tests + run command
- [x] Constraints — backward compat, per-strategy budget, integer cents, log-not-raise
- [x] Checklist — present
- [x] Related — parent issue, dependency, user story doc
Traceability
- [x] story:portfolio-builder label — AI Portfolio Builder
- [x] story note verified — found in project-prediction-assistant user-stories section (key: portfolio-builder, role: Trader)
- [x] arch:rails label — present on board item
- [ ] arch note MISSING — [SCOPE] No
arch-railsnote found in pal-e-docs. This is a project-wide gap: many prediction-assistant board items carryarch:railsbut no backing note exists. Recommend creatingarch-railsas a project-level architecture note covering the Rails 8.1 + Hotwire + Solid Queue stack. - [x] Forgejo issue — #89, open
File Targets
- [x]
app/services/order_service.rb— verified: exists (14k), containsOrderServiceclass withplace_order,cancel_order,check_fill_statusmethods. Already has@dry_runpattern withhandle_dry_runmethod. Thebot:param is typed asStrategy, sobot.trading_enabled?andbot.budget_centsaccess path is valid once sub-ticket 1 adds those fields. - [x]
test/services/order_service_test.rb— verified: exists (18k), established test file for OrderService - [x] NOT-TOUCH:
app/models/strategy.rb— verified: currently has notrading_enabledorbudget_centsfields (correct, those come from sub-ticket 1) - [x] NOT-TOUCH: Bot job files — verified: jobs (
sweep_eligible_job.rb,pregame_threshold_job.rb) do not call OrderService directly; they delegate through bot service classes
Repo Placement
OK. Issue #89 filed on ldraney/prediction-assistant, all file targets are in that repo. Single-repo change.
Dependencies
- Depends on sub-ticket 1: issue #88 "Trading fields migration + Strategy model validations" (board item #1764, currently in backlog). This dependency is documented in the Lineage and Context sections.
trading_enabled?andbudget_centsmust exist on Strategy before this ticket can be implemented. - No downstream blockers identified — this ticket is a prerequisite for sub-ticket 3 (Activation UI panel, #90).
Acceptance Criteria
7 ACs are well-defined and testable by an agent:
- AC 1-2:
trading_enabled?check + dry_run forcing — verifiable via unit test assertions on return value - AC 3-5: Budget enforcement — verifiable via unit tests with known trade amounts
- AC 6: ActivityLog recording — verifiable by asserting
ActivityLog.countchange - AC 7: Backward compatibility — verifiable by running existing test suite unchanged
Run command is valid:
bin/rails test test/services/order_service_test.rbBlast Radius
- Callers safe:
PregameStackerBotandLateGameLockBotboth createOrderService.new(client:, dry_run:)and passbot: strategytoplace_order. The new enforcement is internal to OrderService — callers need no changes. - cancel_order not affected: ACs scope enforcement to "placing any order" — cancellations are correctly excluded since the concern is preventing real money outflow.
- No sibling service concern: OrderService is the single shared trade execution service; no similar pattern exists elsewhere that would need the same fix.
Decomposition Assessment
- File targets: 2 files in 1 repo — under the 3-file threshold
- Acceptance criteria: 7 — over the 5-AC threshold on paper, but all are tightly coupled variations of one behavioral change (guard clause + budget check in a single method)
- Estimated agent work: well under 5 minutes — add guard clause to
place_order, add budget helper method, add ~5 test cases to existing test file - No decomposition needed
Recommendation
[SCOPE]Create architecture notearch-railscovering the Rails 8.1 + Hotwire + Solid Queue stack. This is a project-wide gap affecting many board items, not specific to this ticket. Non-blocking for this review.