Plan Generator
Generates a high-level implementation plan from ticket requirements and research findings. Surfaces decision points, alternatives, risks, and pivot triggers. Iterates with human feedback until approved.
Configuration
Uses the production API by default. No configuration needed for read operations.
Defaults (no setup required):
- API URL:
https://api-gateway-856475788601.us-central1.run.app - Read-only endpoints at
/public/*require no authentication
For write operations (state transitions), set:
export PIPELINE_API_KEY="..." # Get from GCP Secret Manager or ask admin
Local directory for working artifacts:
PIPELINE_DIR="${PIPELINE_DIR:-$HOME/repos/ticket-to-pr-pipeline}"
Prerequisites
- Ticket exists in API (via
ticket-intake) research-report.mdexists locally as working artifact- Human has reviewed and approved the research
PIPELINE_API_KEYset for write operations (get from GCP Secret Manager or ask admin)
Workflow
0. Verify Pipeline Ticket Exists
Before proceeding, confirm a ticket exists in the pipeline API. If not, run ticket-intake first.
const ticket = await client.getTicket(ticketId)
if (!ticket) {
throw new Error('❌ No pipeline ticket found. Run ticket-intake first to register this ticket in the pipeline API.')
}
If no ticketId is available, search by Notion page ID or list recent tickets:
const ticket = await client.findByNotionId(notionPageId)
if (!ticket) {
console.error('❌ No pipeline ticket found for this Notion page. Run ticket-intake first.')
process.exit(1)
}
const ticketId = ticket.id
1. Load Context
Get ticket data via the Pipeline API and read local research artifact:
import { PipelineClient } from '@pipeline/client'
const client = new PipelineClient({
apiUrl: process.env.PIPELINE_API_URL || 'https://api-gateway-856475788601.us-central1.run.app',
agentId: process.env.AGENT_ID ?? 'plan-generator',
})
// Get ticket data from API
const ticket = await client.getTicket(ticketId)
// Transition to PLANNING state
await client.transitionState(ticketId, 'PLANNING', 'Starting plan generation')
// Read local research artifact
// research-report.md in working directory
Extract from ticket:
- Title and description
- Acceptance criteria
- Affected files/areas
Extract from research-report.md:
- Recommended patterns
- Similar implementations found
- Risks identified
- Open questions
2. Generate High-Level Plan
Create the plan following this structure:
# Implementation Plan: {Ticket Title}
## Goal
One sentence describing what we're building and why.
## Proposed Approach
High-level description of the solution (2-3 paragraphs max).
## Decision Points
### Decision 1: {Title}
**Options:**
- **Option A:** {description}
- Pros: ...
- Cons: ...
- **Option B:** {description}
- Pros: ...
- Cons: ...
**Recommended:** Option {X}
**Rationale:** {why this option}
**Pivot Trigger:** {when to reconsider this decision}
### Decision 2: ...
## Architecture Overview
How the solution fits into the existing codebase. Reference patterns from research.
## Files to Modify
- `path/to/file.ts` - {what changes}
- `path/to/other.vue` - {what changes}
## Files to Create
- `path/to/new.ts` - {purpose}
## Risks & Mitigations
| Risk | Likelihood | Impact | Mitigation |
| ------ | ------------ | ------------ | ---------------- |
| {risk} | Low/Med/High | Low/Med/High | {how to address} |
## Dependencies
- External libraries needed (if any)
- Other PRs that need to merge first
- Backend changes required
## Testing Strategy
- Unit tests needed
- E2E tests needed
- Manual testing approach
## Estimated Scope
- Lines of code: ~{estimate}
- Complexity: Low/Medium/High
- PR split recommendation: Single/Vertical/Stacked
## Open Questions
- Questions that need answers before implementation
---
_Revision: 1_
_Generated: {timestamp}_
3. Save Plan
Save the plan as a local working artifact:
# Save plan locally
echo "$PLAN_CONTENT" > "plan.md"
4. Present for Review
Print the full plan, then prompt:
Please review the plan above.
Options:
1. Approve and continue to implementation tasks
2. Provide feedback for revision
3. Request more research on specific areas
Your response:
5. Handle Feedback
If feedback provided:
- Revise the plan addressing the feedback
- Increment revision number
- Append revision history to the plan
- Re-present for review
If more research requested:
- Note which areas need research
- Update status to "research-needed"
- Return to research-orchestrator
If approved:
- Transition state via API
- Prompt to continue to task generation
// On approval
await client.transitionState(ticketId, 'TASKING', 'Plan approved, ready for task generation')
Decision Point Guidelines
Decision points are critical. For each significant choice:
- Identify alternatives - What else could we do?
- Evaluate trade-offs - Pros/cons of each
- Recommend with rationale - Why this choice?
- Define pivot triggers - When would we switch?
Examples of decision points:
- Which component pattern to use (composable vs. store vs. props)
- Where to place new code (new file vs. extend existing)
- API design choices
- State management approach
- Testing strategy (unit vs. E2E focus)
Scope Assessment
When estimating scope:
- Small (< 200 LOC): Single PR, straightforward
- Medium (200-500 LOC): Single PR, may need careful review
- Large (500+ LOC): Consider splitting into multiple PRs
If scope suggests splitting, recommend:
- Vertical slices: Each PR delivers working feature subset
- Stacked PRs: Layered changes building on each other
Revision History Format
When revising, append to the plan:
---
## Revision History
### Revision 2 - {timestamp}
**Feedback:** {summary of feedback}
**Changes:**
- Changed X to Y because...
- Added consideration for Z...
Output Artifacts
| File | Location | Description |
|---|---|---|
| plan.md | ./plan.md | The implementation plan |
State transitions are recorded in the API.
Next Step
After plan approval, invoke plan-to-tasks to convert the plan into implementation tasks.
Error Handling
import { PipelineAPIError } from '@pipeline/client'
try {
const ticket = await client.getTicket(ticketId)
} catch (error) {
if (error instanceof PipelineAPIError) {
console.error(`API Error ${error.status}: ${error.message}`)
// Handle specific status codes (404 = not found, 409 = invalid transition, etc.)
}
throw error
}
Missing Configuration
❌ Missing required environment variables.
PIPELINE_API_KEY must be set for write operations. Get it from GCP Secret Manager or ask admin.
