Planning Workflow

Planning Workflow #

The planning workflow generates comprehensive implementation plans for Linear issues using Claude Code’s Context Engineering framework.

Overview #

When a user mentions @Tofie plan in a Linear issue comment, Tofie creates a detailed implementation plan that includes:

  • Analysis of issue requirements and comments
  • Background research on existing codebase
  • Phase-by-phase implementation roadmap
  • Technical specifications
  • Risk assessment and success criteria

Trigger #

User Action: Comment on a Linear issue with:

@Tofie plan

Alternative commands:

@Tofie plan this issue
@Tofie create a plan
@Tofie planning

#

Workflow Steps

1. Webhook Reception (n8n) #

What happens:

  • Linear sends webhook to n8n when comment is created
  • Webhook payload includes full issue context

Data received:

{
  "action": "create",
  "type": "Comment",
  "data": {
    "id": "comment-123",
    "body": "@Tofie plan",
    "issue": {
      "id": "issue-456",
      "identifier": "ENG-1144",
      "title": "Add date range filtering",
      "description": "Full description...",
      "state": {
        "name": "Todo"
      },
      "comments": [...]
    },
    "user": {
      "name": "John Doe"
    }
  }
}

2. Command Parsing (n8n) #

What happens:

  • n8n checks if comment body contains “@Tofie”
  • Extracts command type (plan, implement, review, pr)
  • Validates that issue is in appropriate state

Validation:

// Check for Tofie mention
if (!comment.body.toLowerCase().includes("@tofie")) {
  return; // Not a Tofie command
}

// Extract command
const command = extractCommand(comment.body); // "plan"

// Check issue state
if (issue.state.name !== "Todo" && command === "plan") {
  addLinearComment(
    issue.id,
    "⚠️ Planning can only be triggered from Todo state"
  );
  return;
}

3. Linear Status Update (n8n) #

What happens:

  • Issue status changed to “Planning”
  • Comment added to Linear confirming work has started

API Call:

mutation {
  issueUpdate(id: "issue-456", input: { stateId: "planning-state-id" }) {
    success
  }
}

Comment added:

πŸ€– Tofie Planning Started

I'm creating a comprehensive implementation plan for this issue.

**Status**: Planning in progress
**Expected time**: 2-5 minutes
**Next steps**: Once complete, I'll post the plan here

Worktree: `/home/coder/trees/eng-1144`

4. Build Input JSON (n8n) #

What happens:

  • Extracts all relevant data from Linear webhook
  • Structures it as JSON for script consumption

JSON Structure:

{
  "branchName": "john/eng-1144-feat-add-filtering",
  "issueIdentifier": "ENG-1144",
  "agentSessionId": "session-abc-123",
  "thoroughness": "medium",
  "project": {
    "id": "proj-123",
    "name": "BonsAI Core",
    "key": "ENG"
  },
  "issue": {
    "id": "issue-456",
    "identifier": "ENG-1144",
    "title": "Add date range filtering to invoice list",
    "description": "Users need to filter invoices by date range for reporting...",
    "labels": ["feature", "webapp"],
    "comments": [
      {
        "id": "comment-789",
        "body": "Make sure to handle timezone differences",
        "createdAt": "2025-11-01T10:00:00Z",
        "user": { "name": "Alice" }
      }
    ]
  }
}

5. SSH Connection (n8n β†’ Coder) #

What happens:

  • n8n establishes SSH connection to Coder instance
  • Executes appropriate planning script

SSH Command:

ssh coder@coder-instance.internal \
  "cd /home/coder/bonsai/tools/local/scripts/tofie && \
   ./planning.sh"  # or planning-subagent.sh

stdin: JSON input piped to script stdout: JSON result captured by n8n stderr: Logs (for debugging if needed)

6. Script Execution (Coder Instance) #

6a. Worktree Creation #

What happens:

  • Script checks if worktree already exists
  • Creates new worktree from main branch if needed

Commands executed:

# Check if worktree exists
if [[ -d "/home/coder/trees/john-eng-1144" ]]; then
  log_warn "Worktree already exists, reusing it"
else
  # Create new worktree
  git worktree add \
    -b "john/eng-1144-feat-add-filtering" \
    "/home/coder/trees/john-eng-1144" \
    main
fi

Result:

/home/coder/trees/john-eng-1144/
β”œβ”€β”€ apps/
β”œβ”€β”€ libs/
β”œβ”€β”€ tools/
└── [full codebase on new branch]

6b. Metadata Creation #

What happens:

  • Creates .plans/ directory (gitignored)
  • Writes linear-metadata.json with full issue context
  • Writes n8n-metadata.json with webhook configuration

Files created:

.plans/linear-metadata.json:

{
  "branchName": "john/eng-1144-feat-add-filtering",
  "issueIdentifier": "ENG-1144",
  "agentSessionId": "session-abc-123",
  "project": { ... },
  "issue": { ... },
  "createdAt": "2025-11-03T10:00:00Z",
  "updatedAt": "2025-11-03T10:00:00Z"
}

.plans/n8n-metadata.json:

{
  "event_server_url": "${TOFIE_N8N_EVENT_URL}",
  "signing_key": "${TOFIE_N8N_SIGNING_KEY}",
  "createdAt": "2025-11-03T10:00:00Z"
}

6c. Claude CLI Invocation #

Standard Planning (planning.sh):

Prompt built:

Please create a comprehensive implementation plan for the following Linear issue.

Project: BonsAI Core
Issue: ENG-1144 - Add date range filtering to invoice list
Branch: john/eng-1144-feat-add-filtering

Issue Description:
Users need to filter invoices by date range for reporting...

Issue Comments (1):
---
Comment by Alice on 2025-11-01T10:00:00Z:
Make sure to handle timezone differences
---

Use the /tofie-plan command with the following parameters:
- Branch name: john/eng-1144-feat-add-filtering
- Linear issue ID: ENG-1144
- Agent session ID: session-abc-123

The worktree has already been created at: /home/coder/trees/john-eng-1144
The Linear metadata (including full issue and comments) has been stored at: .plans/linear-metadata.json
The n8n metadata has been stored at: .plans/n8n-metadata.json

IMPORTANT: When creating the plan:
1. Consider ALL comments in the issue - they may contain important requirements
2. Address any questions or concerns raised in the comments
3. Include a section that references relevant comments
4. If comments conflict, note this and propose a resolution

Please proceed with creating the implementation plan following the Context Engineering framework.

Command executed:

/home/coder/.local/bin/claude \
  --print \
  --output-format text \
  --model sonnet \
  --permission-mode acceptEdits \
  "$CLAUDE_PROMPT"

Subagent Planning (planning-subagent.sh):

Prompt includes additional instructions:

**Please use the tofie-planner SUBAGENT to create this plan.**

The subagent should:
1. Perform thorough research across the codebase
2. Analyze architectural patterns and constraints
3. Create a comprehensive implementation plan using Context Engineering
4. Store the plan in .plans/PLAN.md
5. Consider ALL comments in the issue
...

**CRITICAL FORMATTING REQUIREMENT - Linear Collapsible Sections:**
The PLAN.md file MUST use Linear's collapsible section syntax:
- Start: `+++ Section Title`
- End: `+++`
- Keep Executive Summary visible
- Wrap detailed sections in collapsible blocks

Command executed:

/home/coder/.local/bin/claude \
  --print \
  --output-format text \
  --model sonnet \
  --dangerously-skip-permissions \
  "$CLAUDE_PROMPT"

6d. Claude Execution #

What Claude does:

  1. Research Phase

    • Searches codebase for related functionality
    • Identifies existing patterns and conventions
    • Finds integration points
  2. Analysis Phase

    • Analyzes all issue comments for requirements
    • Identifies constraints and dependencies
    • Checks for conflicting requirements
  3. Planning Phase

    • Structures plan using Context Engineering framework
    • Creates phase-by-phase implementation roadmap
    • Includes technical specifications
  4. Documentation Phase

    • Writes PLAN.md with Linear collapsible sections
    • Saves to .plans/PLAN.md

6e. Plan Generation #

PLAN.md Structure:

# Add Date Range Filtering - Implementation Plan

## Executive Summary

- Add date range filtering to invoice list view
- Impacts: webapp frontend, API endpoint, database query
- Expected completion: 6-8 hours
- Linear issue: https://linear.app/bonsai/issue/ENG-1144

## Comments Analysis

**Key takeaways from issue comments:**

- Timezone handling is critical (Alice's comment)
- Must support both start and end date filtering

+++ Detailed Comments Analysis

### Key Comments

1. **Comment by Alice on 2025-11-01**:

   > Make sure to handle timezone differences

   **Impact**: Must convert all dates to UTC for consistent filtering
   **Resolution**: Phase 2 includes timezone conversion logic

+++

+++ Background Research

### Existing Code Analysis

- Invoice list: `apps/webapp/src/app/(authenticated)/invoices/page.tsx`
- API endpoint: `apps/bonsapi/src/controllers/invoice.rs`
- Database query: `apps/bonsapi/src/repositories/invoice.rs`

### Current Implementation

- Basic pagination exists
- No date filtering currently
- Uses Tanstack Query for data fetching

+++

## Implementation Phases

**High-level overview:**

- Phase 1: Database & API (2 hours)
- Phase 2: Frontend Components (3 hours)
- Phase 3: Integration & Testing (2 hours)

**Total estimated effort:** 6-8 hours

+++ Phase 1: Database & API

**Tasks:**

1. Update `InvoiceFilter` struct with date fields
2. Modify SQL query to include date WHERE clauses
3. Add API endpoint parameters
4. Update OpenAPI spec

**Files to modify:**

- `apps/bonsapi/src/models/invoice.rs`
- `apps/bonsapi/src/repositories/invoice.rs`
- `apps/bonsapi/src/controllers/invoice.rs`
- `apps/bonsapi/docs/openapi/invoices.yaml`

+++

+++ Phase 2: Frontend Components

**Tasks:**

1. Create date range picker component
2. Integrate with existing filter UI
3. Handle timezone conversion (UTC)
4. Update Tanstack Query params

**Files to create/modify:**

- `apps/webapp/src/components/invoices/DateRangeFilter.tsx` (new)
- `apps/webapp/src/app/(authenticated)/invoices/page.tsx`
- `apps/webapp/src/lib/hooks/useInvoices.ts`

+++

+++ Phase 3: Integration & Testing

**Tasks:**

1. Manual testing of date filtering
2. Test timezone edge cases
3. Update E2E tests
4. Run `mise ci` to ensure all checks pass

**Test cases:**

- Filter by start date only
- Filter by end date only
- Filter by date range
- Handle timezone boundaries

+++

+++ Technical Specifications

### API Changes

**Endpoint**: `GET /api/invoices`

**New Query Parameters**:

- `start_date` (optional): ISO 8601 date string
- `end_date` (optional): ISO 8601 date string

**Example**:

GET /api/invoices?start_date=2025-11-01&end_date=2025-11-30


**Response**: Same as existing, filtered by date range

### Database Changes

**No schema changes required** - uses existing `created_at` timestamp

**Query modification**:
```sql
SELECT * FROM invoices
WHERE created_at >= $start_date
  AND created_at <= $end_date
ORDER BY created_at DESC

+++

+++ Risk Assessment

Potential Issues:

  • Timezone conversion errors (HIGH)

    • Mitigation: Always use UTC, add tests for timezone edge cases
  • Performance with large date ranges (MEDIUM)

    • Mitigation: Database index on created_at exists, pagination limits results
  • Breaking changes to API (LOW)

    • Mitigation: Parameters are optional, backward compatible

+++

+++ Success Criteria

  • Users can filter invoices by start date
  • Users can filter invoices by end date
  • Users can filter by date range (both dates)
  • Timezone handling works correctly (UTC conversion)
  • API returns correct results for all scenarios
  • E2E tests pass
  • mise ci passes (format, lint, tests)

+++


### 7. Script Output (Coder β†’ n8n)

**What happens**:
- Script validates PLAN.md was created
- Returns JSON result via stdout

**Success Output**:
```json
{
  "success": true,
  "message": "Planning completed successfully",
  "worktreePath": "/home/coder/trees/john-eng-1144",
  "planPath": "/home/coder/trees/john-eng-1144/.plans/PLAN.md",
  "linearMetadataPath": "/home/coder/trees/john-eng-1144/.plans/linear-metadata.json",
  "n8nMetadataPath": "/home/coder/trees/john-eng-1144/.plans/n8n-metadata.json",
  "claudeOutput": "βœ… success\nPlan file path: .plans/PLAN.md",
  "timestamp": "2025-11-03T10:05:00Z"
}

Error Output:

{
  "success": false,
  "error": "Failed to create worktree: branch already exists",
  "timestamp": "2025-11-03T10:05:00Z"
}

8. Linear Update (n8n) #

What happens:

  • n8n parses script output
  • Posts plan to Linear as a comment
  • Updates issue status to “Planned”

Comment posted:

βœ… Planning Complete

I've created a comprehensive implementation plan for this issue.

## Summary

- **Estimated time**: 6-8 hours
- **Phases**: 3 (Database/API, Frontend, Integration)
- **Files to modify**: 7

## Plan Details

[Full PLAN.md content with collapsible sections]

## Next Steps

Ready for implementation! Comment `@Tofie implement` when you're ready to proceed.

---

πŸ“ Worktree: `/home/coder/trees/john-eng-1144`
πŸ“„ Plan: `.plans/PLAN.md`

Status update:

mutation {
  issueUpdate(id: "issue-456", input: { stateId: "planned-state-id" }) {
    success
  }
}

Decision Points #

Standard vs Subagent Planning #

Use Standard Planning (planning.sh) when:

  • Single straightforward plan needed
  • Issue is well-defined
  • Time is a priority (2-5 minutes)

Use Subagent Planning (planning-subagent.sh) when:

  • Complex issue requiring deep research
  • Multiple approaches need exploration
  • Thoroughness > speed (5-15 minutes)
  • User explicitly requests “thorough” planning

Configuration: Set thoroughness field in input JSON:

  • "quick" β†’ Standard planning
  • "medium" β†’ Standard planning (default)
  • "very thorough" β†’ Subagent planning

Error Scenarios #

Worktree Already Exists #

Cause: Previous planning attempt didn’t cleanup

Script behavior:

  • Reuses existing worktree
  • Logs warning message
  • Continues normally

Resolution: No action needed, automatic recovery

PLAN.md Not Created #

Cause: Claude execution failed or permission issues

Script behavior:

  • Returns success=false
  • Includes Claude output in error message

Resolution:

  • Check Claude CLI logs
  • Retry planning
  • Manual intervention if persists

Invalid JSON Input #

Cause: n8n parsing error or webhook malformed

Script behavior:

  • Immediate validation failure
  • Returns error before any work

Resolution:

  • Check n8n workflow configuration
  • Validate webhook payload format

Monitoring #

Success Metrics #

Track in n8n or monitoring dashboard:

  • Planning completion rate (%)
  • Average execution time
  • Error rate by error type
  • User satisfaction (via Linear reactions)

Log Analysis #

Script logs (stderr):

[INFO] Reading JSON input from stdin...
[INFO] Parsed input:
[INFO]   Branch: john/eng-1144-feat-add-filtering
[INFO]   Issue: ENG-1144 - Add date range filtering...
[INFO]   Project: BonsAI Core
[INFO]   Comments: 1
[INFO] Project root: /home/coder/bonsai
[INFO] Worktree path: /home/coder/trees/john-eng-1144
[INFO] Creating worktree from main branch...
[INFO] Worktree created
[INFO] Creating metadata files...
[INFO] Metadata files created
[INFO] Executing Claude Code CLI in worktree...
[INFO] Claude Code execution completed
[INFO] Plan created: .plans/PLAN.md (15234 bytes)
[INFO] Planning completed successfully!

Best Practices #

For Users #

  1. Provide clear issue descriptions

    • Include acceptance criteria
    • Add examples if applicable
    • Reference related issues
  2. Add clarifying comments

    • Tofie reads all comments
    • Use comments to guide the plan
    • Flag constraints or requirements
  3. Review plans before implementing

    • Plans are suggestions, not gospel
    • Comment on the plan if changes needed
    • Can re-run planning if needed

For Developers #

  1. Keep planning scripts updated

    • Add new sections as needed
    • Update prompts based on feedback
    • Test with various issue types
  2. Monitor plan quality

    • Review generated plans periodically
    • Identify common issues
    • Improve prompts iteratively
  3. Handle edge cases

    • Empty issue descriptions
    • No comments
    • Very long issues