Review: Implement billing follow-up agent for Westside Basketball
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Feature
- [x] Lineage -- Standalone, first ticket for Nemo project
- [x] Repo -- ldraney/nemo
- [x] User Story -- well-formed (As Marcus, I want...)
- [x] Context -- thorough background on the 28-player billing campaign
- [x] File Targets -- 8 files to create, 2 files excluded
- [x] Feature Flag -- none
- [x] Acceptance Criteria -- 9 criteria
- [x] Test Expectations -- 4 test items + run command
- [x] Constraints -- 6 constraints listed
- [x] Checklist -- present
- [x] Related -- present
All required template sections are present.
Traceability
- [x] story:billing-follow-up label -- present on board item
- [ ] story note MISSING --
project-nemopage does not exist (404). [SCOPE] Create project pageproject-nemowith user-stories section containing the billing-follow-up story. - [x] arch:nemo-agent label -- present on board item
- [ ] arch note MISSING --
arch-nemo-agentnote does not exist (404). [SCOPE] Create architecture notearch-nemo-agentfor the agent component. - [x] Forgejo issue -- ldraney/nemo#1, state: open
File Targets
- [x]
src/webhook.py-- to create; repo is currently docs-only, path is valid - [x]
src/agent.py-- to create; consistent with architecture doc - [x]
src/tools.py-- to create; consistent with architecture doc - [x]
src/config.py-- to create; consistent with architecture doc - [x]
Dockerfile-- to create; standard for containerized service - [x]
pyproject.toml-- to create; standard Python project file - [x]
.woodpecker/ci.yaml-- to create; matches platform CI convention - [x]
.pre-commit-config.yaml-- to create; matches platform convention - [x]
docs/-- excluded (already exists in repo) - [x]
projects/westside-billing-agent/workflow.md-- excluded (exists in repo)
All file targets are valid for a greenfield service in a docs-only repo.
Repo Placement
Issue is filed on
ldraney/nemo and all file targets are in the nemo repo -- correct. However, there is an undocumented cross-repo dependency:- AC #2 references
GET /api/v1/players/:id/billingbut the westside-basketball Rails app has NO JSON API endpoints at all. The routes.rb has noapi/v1namespace and no API controllers exist. - The workflow doc (
projects/westside-billing-agent/workflow.md) explicitly lists "JSON API endpoints" under "What Is NOT Built" and proposes two options: (A) JSON API on Rails, or (B) Direct API access via kubectl/Stripe/Gmail. - The ticket implicitly assumes Option A without creating a companion westside-basketball ticket for the API endpoints.
- AC #4 references
ParentMailer#billing_followupbut that method does not exist. ParentMailer only hasannouncement,payment_reminder, andquick_send.
The ticket must either: (a) add a cross-repo dependency ticket on westside-basketball for JSON API + mailer work, or (b) rewrite the approach to use Option B (direct API access) and clarify which mailer method to use.
Dependencies
- Only item on board-nemo; no board-level blockers or blocked items.
- Cross-repo dependency (undocumented): Rails JSON API endpoints (
/api/v1/players/:id/billing,PATCH /api/v1/orders/:id,POST /api/v1/orders,POST /api/v1/emails/send,GET /api/v1/emails/inbox) do not exist in westside-basketball. No ticket exists to create them. - Cross-repo dependency (undocumented):
ParentMailer#billing_followupdoes not exist in westside-basketball. Onlyannouncement,payment_reminder,quick_sendexist. - Operational dependencies: Postmark account + DNS setup, Anthropic API key, Stripe API key, k8s namespace creation -- not code dependencies but need to exist before deployment.
Acceptance Criteria
9 acceptance criteria listed. Assessment:
- AC #1 (Postmark triggers agent) -- testable via webhook mock
- AC #2 (Agent pulls from Rails JSON API) -- BLOCKED: API does not exist in the Rails app
- AC #3 (Standard fixes) -- testable with mock data
- AC #4 (Draft billing email via Postmark) -- references nonexistent
billing_followupmailer; also, the architecture doc says Nemo sends via Postmark outbound, but the workflow doc referencesParentMailer(Rails Gmail delivery). These contradict each other. - AC #5-6 (Marcus approval flow) -- testable
- AC #7 (One player at a time) -- testable
- AC #8 (Persistent state on restart) -- testable
- AC #9 (Custom email handling for edge cases) -- vague; what edge cases specifically? "no-show, disputed, left program" are mentioned in Constraints but not mapped to specific AC behaviors
Blast Radius
- Nemo is a new standalone service, so blast radius within its own repo is contained.
- Cross-repo impact on westside-basketball is the primary concern: JSON API endpoints, mailer methods, and potentially auth token setup.
- No existing Postmark integration anywhere in the infrastructure -- this is net-new infrastructure.
- Email sending conflict: architecture.md says Nemo sends via Postmark outbound, workflow.md says emails go through
ParentMailer(Rails + Gmail). The ticket must pick one approach.
Decomposition Assessment
NEEDS DECOMPOSITION -- route to skill-decompose-ticket
- 8 file targets in 1 repo -- exceeds the 3+ file threshold
- 9 acceptance criteria -- exceeds the 5 AC threshold
- Estimated agent work far exceeds 5 minutes -- building an entire FastAPI service with Claude agent loop, Postmark webhook handling, tool definitions, persistent state, Dockerfile, CI pipeline, and pre-commit config is a multi-hour effort
- Cross-repo dependency -- Rails JSON API and/or mailer work needs a separate ticket on westside-basketball
Suggested decomposition axes:
- Skeleton service (FastAPI webhook + config + Dockerfile + CI + pre-commit) -- infra only, no agent logic
- Agent loop core (agent.py + tools.py) -- Claude API integration with tool use
- Postmark integration (inbound parsing + outbound sending + signature validation)
- Billing workflow logic (standard fixes, email drafting, approval parsing)
- State management (persistent state file, resume on restart)
- Cross-repo: westside-basketball JSON API endpoints (separate repo ticket)
Recommendation
[SCOPE]Create project pageproject-nemowith user-stories section containing the billing-follow-up story entry.[SCOPE]Create architecture notearch-nemo-agentfor the agent component. The architecture.md in the repo is detailed -- this can be derived from it.[BODY]Resolve the data access approach: either commit to Option A (JSON API on Rails, which requires a cross-repo dependency ticket on westside-basketball) or Option B (direct API access via Stripe/kubectl). Update AC #2 accordingly.[BODY]Resolve the email sending approach: architecture.md says Postmark outbound, workflow.md saysParentMailer(Rails + Gmail). Pick one and update AC #4 and the File Targets section.[BODY]Fix AC #4:ParentMailer#billing_followupdoes not exist. Either referenceannouncement/quick_sendor add a cross-repo dependency to create the method.[BODY]AC #9 (custom email handling) is too vague for agent verification. Enumerate the specific edge cases and expected agent behavior for each.[DECOMPOSE]8 file targets and 9 AC across a full greenfield service far exceed the 5-minute rule. Route toskill-decompose-ticketfor sub-ticket creation. Suggested decomposition: skeleton service, agent loop, Postmark integration, billing workflow, state management, and cross-repo Rails API work.