Pre-Workflow Conversations: The Controller Pattern in CodeMachine

Published: (January 18, 2026 at 11:00 AM EST)
5 min read
Source: Dev.to

Source: Dev.to

Agentic Workflows with a Controller Phase

When building agentic workflows, a common pattern emerges: before the autonomous pipeline runs, someone needs to gather requirements.

CodeMachine v0.8.0 introduces the Controller pattern, a first‑class way to have a conversation with an AI product owner (PO) before your workflow executes.

This walkthrough demonstrates a spec‑driven development workflow where a PO agent gathers requirements, then hands off to specialized agents for analysis, architecture, and implementation.

Why a Separate Controller?

Multi‑agent workflows usually start with a prompt and run autonomously.
Real development, however, needs:

IssueWhy it matters
Session managementThe PO conversation should persist across interruptions.
Handoff clarityWhen does the conversation end and execution begin?
Return capabilityWhat if you need to talk to the PO mid‑workflow?

Visual Overview

┌─────────────────────────────────────────────────────────────┐
│                    Controller Phase                         │
│              (Interactive PO conversation)                  │
│                                                             │
│   User ←→ spec-po agent (session persisted)                 │
│                                                             │
│   [Enter with empty input] → Confirmation Dialog            │
└─────────────────────────────────────────────────────────────┘

                              ▼ workflow:controller-continue
┌─────────────────────────────────────────────────────────────┐
│                   Execution Phase                           │
│              (Autonomous agent pipeline)                    │
│                                                             │
│   spec-analyst → spec-architect → spec‑api‑designer → …      │
│                                                             │
│   [Press C] → Return to Controller Dialog                    │
└─────────────────────────────────────────────────────────────┘

                              ▼ workflow:return-to-controller
┌─────────────────────────────────────────────────────────────┐
│                 Return to Controller                        │
│          (Pause workflow, resume PO session)                │
│                                                             │
│   User ←→ spec-po agent (same session)                      │
│                                                             │
│   [Enter with empty input] → Resume Workflow                │
└─────────────────────────────────────────────────────────────┘

Declaring the Controller in Code

export default {
    name: 'Spec-Driven Development',
    controller: controller('spec-po', {}),   // PO agent for pre‑workflow chat
    specification: false,

    steps: [
        separator("∴ Discovery Phase ∴"),
        resolveStep('spec-po', {}),               // PO step (auto‑skipped)
        resolveStep('spec-analyst', {}),

        separator("∴ Design Phase ∴"),
        resolveStep('spec-architect', {}),
        resolveStep('spec-api-designer', {}),

        separator("∴ Implementation Phase ∴"),
        resolveStep('spec-setup', {}),
        resolveStep('spec-impl-orchestrator', {}),

        separator("⟲ Review Loop ⟲"),
        resolveStep('spec-tester', { interactive: false }),
        resolveModule('spec-review', { interactive: false, loopSteps: 2 }),
    ],
};

Key Points

  • controller('spec-po', {}) – declares the PO agent for the pre‑workflow conversation.
  • The same PO agent also appears as step 1; when the controller phase runs, this step is automatically marked as completed (no redundant execution).
  • The controller() function can receive engine/model overrides:
controller('spec-po', {
    engine: 'claude',               // Override engine
    model:  'claude-4.5-sonnet'      // Override model
})

Useful when the PO conversation needs different capabilities than the later steps.

Interaction Flow

Starting the Workflow

┌──────────────────────────────────────────────────────────────┐
│  CodeMachine v0.8.0                                          │
├──────────────────────────────────────────────────────────────┤
│                                                              │
│  ▸ spec-po (Running)                                         │
│                                                              │
│  What would you like to build today?                         │
│──────────────────────────────────────────────────────────────│
│                                                              │
│  > A todo list app with Next.js and SQLite                   │
│                                                              │
└──────────────────────────────────────────────────────────────┘

The conversation continues until you press Enter on an empty line. Then a confirmation dialog appears:

┌────────────────────────────────────────┐
│   Ready to start the workflow?         │
│                                        │
│   [Start]   [Continue Chat]            │
└────────────────────────────────────────┘

Choosing Start triggers workflow:controller-continue, transitioning to the Execution Phase.

Session Persistence

The controller session is saved to disk, e.g.:

{
  "controllerConfig": {
    "agentId": "spec-po",
    "sessionId": "ses_44785e25dffeDZqs8kVN7KbfIx",
    "monitoringId": 1
  },
  "autonomousMode": "true"
}

Benefits

  • Resume on crash – If the CLI crashes mid‑conversation, the session can be restored.
  • Return to controller – Mid‑workflow you can pause and go back to the same PO session.
  • Log viewing – Clicking the completed PO step shows the full conversation history.

Pausing Execution & Returning to the Controller

During the autonomous pipeline, press C to pause:

┌──────────────────────────────────────────────────────────────┐
│  Workflow Pipeline (8 items)                                 │
├──────────────────────────────────────────────────────────────┤
│  … (running steps)                                            │
│                                                              │
│  Press C to return to the PO conversation                     │
└──────────────────────────────────────────────────────────────┘

You are taken back to the Return to Controller view, where you can continue chatting with the PO. When you finish (empty input), the workflow resumes from where it left off.

Summary

  • Controller pattern cleanly separates requirement gathering from autonomous execution.
  • Session persistence enables crash recovery, mid‑workflow returns, and full conversation logs.
  • The same PO agent can act both as a controller and as a regular step, with automatic skipping to avoid duplication.
  • Engine/model overrides give you flexibility to tailor the PO conversation’s capabilities.

With CodeMachine v0.8.0, building robust, spec‑driven, multi‑agent development pipelines becomes straightforward and resilient.

Workflow Overview


│  ✓ Hady [PO] (completed)                                     │
│  ▸ Moaz [Analyst] (running)         ← Paused               │
│  ○ Atef [Architect]                                          │
│  ○ Essam [API]                                               │
│                                                              │
├──────────────────────────────────────────────────────────────┤
│  [C] Controller  [Esc] Stop                                  │
└──────────────────────────────────────────────────────────────┘

Controller Interaction

  • When C is pressed

    1. The current step is aborted.
    2. The workflow state machine enters PAUSE.
    3. The phase switches to “onboarding.”
    4. The controller session resumes.
  • After the conversation

    • Press Enter to resume the workflow from the paused step.

Full Spec‑Driven Workflow (with controller)

export default {
    name: 'Spec-Driven Development',
    controller: controller('spec-po', {}),
    specification: false,

    tracks: {
        question: 'What are we working on?',
        options: {
            new_project: { label: 'New Project' },
            existing_app: { label: 'Existing App' },
            refactor: { label: 'Refactor' },
        },
    },

    conditionGroups: [
        {
            id: 'features',
            question: 'What features does your project have?',
            multiSelect: true,
            conditions: {
                has_ui:   { label: 'Has UI' },
                has_auth: { label: 'Has Authentication' },
                has_db:   { label: 'Has Database' },
            },
        },
    ],

    steps: [
        separator("∴ Discovery Phase ∴"),
        resolveStep('spec-po', {}),
        resolveStep('spec-analyst', {}),

        separator("∴ Design Phase ∴"),
        resolveStep('spec-architect', {}),
        resolveStep('spec-api-designer', {}),

        separator("∴ Implementation Phase ∴"),
        resolveStep('spec-setup', {}),
        resolveStep('spec-impl-orchestrator', {}),

        separator("⟲ Review Loop ⟲"),
        resolveStep('spec-tester', { interactive: false }),
        resolveModule('spec-review', { interactive: false, loopSteps: 2 }),
    ],

    subAgentIds: [
        'spec-dev-data',
        'spec-dev-api',
        'spec-dev-ui',
        'spec-dev-tests',
    ],
};

Requirements & Solutions

RequirementSolution
Requirements clarificationController conversation before execution
Session persistenceSessionID stored in template.json
Clear handoffConfirmation dialog before transition
Mid‑workflow returnC key pauses and resumes controller session
Log viewingMonitoringID registered for completed step
Same agent, no duplicationController step auto‑completed after phase

Why the Controller Pattern?

The Controller pattern fills a critical gap in agentic workflows: the need for a human‑AI conversation before the system proceeds autonomously. By promoting this interaction to a first‑class primitive, we gain:

  • Session persistence – work can be resumed later without loss of context.
  • Clear handoff UX – users explicitly confirm transitions, reducing accidental actions.
  • Mid‑workflow return – users can pause, discuss, and then continue exactly where they left off.

These capabilities let CodeMachine model real‑world development processes more faithfully.

Resources

  • CodeMachine on GitHub
  • Workflow Examples
  • Documentation
Back to Blog

Related posts

Read more »

Rapg: TUI-based Secret Manager

We've all been there. You join a new project, and the first thing you hear is: > 'Check the pinned message in Slack for the .env file.' Or you have several .env...

Technology is an Enabler, not a Saviour

Why clarity of thinking matters more than the tools you use Technology is often treated as a magic switch—flip it on, and everything improves. New software, pl...