Review: email_blast tool for NEMO (re-review)

review-759-2026-04-03-r2 Review

review ready

Verdict: READY

Re-review of board item #759. Previous review (review-759-2026-04-03) was NEEDS_REFINEMENT with one finding: story:WA-S1 label had no matching entry on project-westside-ai-assistant. Fixed by relabeling to story:write-ops.

Template Completeness

  • [x] Type — Feature
  • [x] Lineage — standalone, westside-email-agent capability
  • [x] Repo — forgejo_admin/westside-ai-assistant
  • [x] User Story — clear admin-to-NEMO email flow
  • [x] Context — thorough, references existing patterns and auth
  • [x] File Targets — specific files with modify/do-not-touch
  • [x] Acceptance Criteria — 6 testable items
  • [x] Test Expectations — 3 unit tests with run command
  • [x] Constraints — patterns, auth, prompt guidance
  • [x] Checklist — standard 3-item
  • [x] Related — arch-email, sop-email-send, project-westside-agency, basketball-api #295

Traceability

  • [x] story:write-ops label — "Marcus can update player info and manage teams via GroupMe with confirmation (future — not V1)"
  • [x] story note verified — found in project-westside-ai-assistant user-stories section (key: write-ops)
  • [x] arch:email label — email architecture component
  • [x] arch note verified — arch-email note exists in pal-e-docs (id 1102, project westside-basketball, tagged architecture+active)
  • [x] Forgejo issue — forgejo_admin/westside-ai-assistant#31, open

File Targets

  • [x] app/ai.py — verified: TOOLS list at line 51+, SYSTEM_PROMPT at line 24, write tools with metadata operation=write pattern confirmed, tool execution handler present
  • [x] app/basketball.py — verified: BasketballClient class with _request(method, path, json=...) helper. Has get() and specific write methods but no generic post(). Ticket accurately describes adding post() to mirror get().
  • [x] app/confirmation.py — exists, correctly marked NOT to touch
  • [x] app/groupme.py — exists, correctly marked NOT to touch
  • [x] app/config.py — exists, correctly marked NOT to touch

Repo Placement

OK. Issue filed on forgejo_admin/westside-ai-assistant, all file targets are in that repo. No cross-repo work needed — basketball-api blast endpoint already exists and is deployed.

Dependencies

  • [x] basketball-api #295 (blast endpoint) — satisfied, issue closed, merged, deployed
  • [x] Board item #599 (GroupMe bot go-live) — in_progress. Not a hard blocker; email_blast tool can be built and tested independently
No unresolved dependencies that would block execution.

Acceptance Criteria

6 ACs, all agent-verifiable:
  • AC1: email_blast tool in TOOLS with correct schema — grep/read verification
  • AC2: Tool tagged as write operation — grep verification of metadata
  • AC3: BasketballClient.post() method exists — grep verification
  • AC4: SYSTEM_PROMPT includes email capabilities — read verification
  • AC5: End-to-end flow (user says X, NEMO proposes, user confirms, blast executes) — testable via unit test mock
  • AC6: test_email parameter works — unit test
All criteria are concrete and testable. No ambiguity.

Blast Radius

Low. Changes are additive (new tool + new method). Existing tools and confirmation flow are untouched. basketball-api blast endpoint handles auth and validation — this ticket only adds the client-side caller. No sibling services consume NEMO's tool definitions. Rollback is straightforward (revert two file changes).

Decomposition Assessment

2 files in 1 repo. 6 acceptance criteria. Estimated agent time ~3-4 minutes. All changes are tightly coupled (tool definition + client method + prompt update). No independent subtasks worth parallelizing. No decomposition needed.

Recommendation

No action needed. Previous finding (story label mismatch) has been resolved. Ticket is ready for execution.