Three Bugs, One Victory: The Day We Finally Shipped PM-011
July 12
After three weeks of architectural work, domain modeling, and infrastructure building, yesterday we finally shipped PM-011: complete end-to-end GitHub integration. The victory came down to one focused hour of debugging that fixed three distinct bugs and delivered a working system.
Sometimes the most satisfying moments in software development aren’t the big architectural breakthroughs — they’re the systematic debugging sessions where everything finally clicks into place.
Three weeks in the making
PM-011 started as “add GitHub integration” but quickly became something much bigger. We’d built the orchestration engine, implemented intent classification with real AI, created database persistence, and designed a plugin architecture. All the pieces were there, but they weren’t quite talking to each other properly.
The frustrating part? Each component worked in isolation. The intent classifier was hitting 0.95 confidence scores. The orchestration engine could execute multi-step workflows. The GitHub API integration could create issues. But put them together and… mysterious failures.
The kind of bugs that make you question your life choices.
The debugging session that changed everything
July 12, 5:49 PM. I fired up both Cursor Assistant and Claude Code with a simple mission: fix the remaining bugs blocking PM-011 completion. Three bugs stood between us and a working system.
Bug 1: The context handling error
The symptom: UnboundLocalError when processing certain intents
The cause: workflow_factory.py line 66 referenced intent.context without null checking
The fix: Null-safe context access with (intent.context or {}).get() pattern
Classic defensive programming oversight. The kind of bug that makes you realize you’ve been lucky more than careful.
Bug 2: The missing database enum
The symptom: PostgreSQL error about unknown SUMMARIZE TaskType
The cause: Code added SUMMARIZE enum value but database migration was missing
The fix: Proper Alembic migration following the established pattern
This one was architectural debt catching up with us. We’d been moving fast on domain models but not keeping the database schema in sync.
Bug 3: The domain model consistency violation
The symptom: UI showing “couldn’t generate a summary” despite successful workflow completion
The cause: SUMMARIZE task handler storing results as {"message": response} while UI expected {"analysis": {"summary": "..."}}
The deeper issue: SUMMARIZE wasn't following the established domain pattern that ANALYZE_FILE had set
This was the most interesting bug. Not a coding error, but an architectural consistency violation. The kind of issue that domain-driven design principles are supposed to catch.
The moment of truth
With all three bugs fixed, we ran the comprehensive test suite:
Bug Report
- Input: “Users are complaining that the mobile app crashes when they upload large photos”
- Intent: ANALYSIS/investigate_crash
- Workflow: GENERATE_REPORT
- Result: 2,429 character analysis
- Status: ✅
Explicit Ticket
- “Create a ticket for the new payment integration”
- EXECUTION/create_ticket
- CREATE_TICKET
- GitHub Issue #21
- ✅
Performance Issue
- “The login page is too slow and users are getting frustrated”
- ANALYSIS/performance_analysis
- GENERATE_REPORT
- 2,804 character analysis
- ✅
Feature Request
- “We need to add dark mode support to improve user experience”
- EXECUTION/add_feature
- CREATE_TICKET
- GitHub Issue #22
- ✅
Every. Single. Test. Passed.
Real GitHub issues were created. Comprehensive analyses were generated. The intent classification was working with scary accuracy. The orchestration engine was executing complex workflows flawlessly.
The architectural discovery
But here’s what surprised me: the system was more sophisticated than I’d realized.
The intent classification wasn’t just categorizing requests — it was embedding product management best practices:
Analysis triggers (confidence 0.85): Problem descriptions like “users are complaining” or “X is too slow” → investigate first, understand the issue before creating tickets
Execution triggers (confidence 0.95): Direct action requests like “create a ticket” or “we need to add” → immediate action, clear requirements already provided
The system was preventing ticket spam while enabling quick execution when appropriate. We’d accidentally built PM workflow intelligence into the intent classification.
The production readiness moment
7:06 PM, Claude Code delivered the verdict: “The system is ready for production use with complete end-to-end GitHub integration functionality.”
Three weeks of architectural work. Dozens of commits. Multiple AI assistants coordinating fixes. All culminating in one beautiful sentence.
That’s the thing about complex systems work — progress feels incremental until suddenly it doesn’t. You’re debugging individual components for weeks, and then one day everything clicks into place and you have something that actually works.
What we learned about AI-assisted debugging
The July 12 session validated something important about working with multiple AI assistants:
Cursor Assistant excelled at systematic investigation and following established patterns for the database migration.
Claude Code was brilliant at rapid pattern matching and finding the domain model inconsistency.
Me was essential for knowing when to stop and ship instead of looking for more problems to solve.
The collaboration pattern that emerged: human sets objectives, AIs execute with different strengths, human makes the ship/don’t-ship call.
The honest assessment
Is PM-011 perfect? Not even close. There’s still technical debt, the error handling could be more graceful, and we haven’t built the learning loops that will make the system truly intelligent over time.
But it works. Real GitHub issues get created from natural language. Complex analyses get generated that actually provide value. The intent classification understands the difference between problems to investigate and features to build.
Sometimes “it works” is exactly what you need.
Looking forward
With PM-011 shipped, we can finally move beyond infrastructure and start building the capabilities that make Piper Morgan genuinely useful. Multi-project support, learning from feedback, cross-system orchestration.
But for now, we’re celebrating. Three bugs, one hour, three weeks of victory.
The prototype is officially dead. Long live the platform.
