Skip to content

feat(taskctl): Phase 5 — PM prompt migration and agent definitions into codebase #208

@randomm

Description

@randomm

Context

Part of the taskctl epic (#201). Depends on all previous phases (#202#207) being complete and tested.

What you're building: The final integration step — migrating PM's system prompt from the 10-step manual workflow to a taskctl-based workflow, and moving the developer and adversarial agent definitions from external config files into the OpenCode codebase itself.

This phase has no new TypeScript modules to build. It's about configuration, prompts, and making the end-to-end flow actually work in practice.

Background reading

Read lievo/plan-v2.md sections: "What PM No Longer Does" and "Phase 5" under Implementation Phases.

Also read the current PM system prompt at ~/.config/opencode/ to understand what's there today and what needs to change.

Part 1: Move agent definitions into the codebase

Currently, the developer and adversarial agent prompts live in ~/.config/opencode/ as external files. This means the pipeline (which runs inside OpenCode) has to rely on those files being present on disk. Instead, move them into packages/opencode/src/agent/agent.ts as programmatic agent definitions, exactly like Composer and Steering were added in earlier phases.

Why this matters

When Pulse spawns a developer or adversarial agent (Phases 3a and 3b), it uses SessionPrompt.prompt({ agent: "developer", ... }). This works by looking up the agent definition in the agent registry. If the definition lives only in an external config file, it might not be found in all environments. By defining it in code, it's guaranteed to always be there.

What to do

  1. Read the current developer agent prompt from ~/.config/opencode/ (the file that defines the developer's system prompt and permissions)
  2. Add a developer-pipeline agent definition to agent/agent.ts:
    {
      name: "developer-pipeline",
      mode: "subagent",
      hidden: true,
      prompt: `... the developer prompt from Phase 3b (simplified: no adversarial, uses taskctl comment) ...`
    }
  3. Do the same for adversarial-pipeline:
    {
      name: "adversarial-pipeline",
      mode: "subagent",
      hidden: true,
      prompt: `... the adversarial prompt (uses taskctl verdict instead of text output) ...`
    }
  4. Update Phase 3a and 3b code to use "developer-pipeline" and "adversarial-pipeline" when spawning agents, rather than the generic "developer" and "adversarial" names

Using distinct names (developer-pipeline vs developer) means:

  • The existing developer agent still works for PM's manual use cases
  • The pipeline uses its own version with the exact prompt it needs
  • No risk of an external config change breaking the pipeline

Part 2: Update PM's system prompt

The current PM system prompt includes a 10-step mandatory workflow for every development task. This needs to be updated to reflect the taskctl-based workflow.

What to remove from PM's prompt

The section that describes the mandatory development workflow steps (research → issue → branch → implementation → PR → code review → CI → deploy → merge). This is now handled automatically by the pipeline.

What to add to PM's prompt

A taskctl-based workflow section. Something like:

## Development Workflow with taskctl

For any development task (feature, bug fix, refactor):

1. RESEARCH    → @explore gathers context (unchanged)
2. GITHUB ISSUE → You create the issue (unchanged)
3. START       → taskctl start <issueNumber>
                 Composer decomposes the issue into tasks automatically.
                 If spec is unclear, Composer returns questions — answer them and retry.
4. MONITOR     → Notifications arrive automatically as tasks complete.
                 Use taskctl status <issueNumber> for a live dashboard.
5. HANDLE ESCALATIONS → If a task gets stuck (3 adversarial cycles), you'll be notified.
                 Use taskctl inspect <taskId> to see the full history.
                 Use taskctl retry, override --skip, or override --commit-as-is.
6. PR + REVIEW → When taskctl status shows all tasks closed:
                 @ops → gh pr create
                 @code-review-specialist → review PR
                 @ops → merge per AGENTS.md policy

## taskctl commands reference

taskctl start <issueNumber>           Start pipeline for a GitHub issue
taskctl status <issueNumber>          Live dashboard — tasks, states, Pulse health
taskctl inspect <taskId>              Full history of a specific task
taskctl stop <jobId>                  Gracefully halt pipeline (work preserved)
taskctl resume <jobId>                Resume a stopped or crashed pipeline
taskctl retry <taskId>                Reset a stuck task for fresh attempt
taskctl override <taskId> --skip      Skip a task, unblock dependents
taskctl override <taskId> --commit-as-is   Commit despite adversarial issues (PM takes responsibility)

What NOT to remove from PM's prompt

  • The research/explore workflow (unchanged)
  • GitHub issue creation (PM still does this)
  • PR creation and merge policy (PM + @ops still handles this after taskctl completes)
  • Memory usage (remory) — unchanged
  • Adversarial review gate for PM's own agent dispatch — PM still does this when manually dispatching agents outside the pipeline
  • Fork governance, AGENTS.md conventions — unchanged

Part 3: Update AGENTS.md

Add a brief section to AGENTS.md explaining the taskctl system to future developers who need to understand the codebase:

## taskctl: Autonomous Task Pipeline

`taskctl` is a built-in tool that automates the development loop for GitHub issues.
PM calls `taskctl start <issueNumber>` and the pipeline handles:
- Decomposing the issue into tasks (Composer)
- Scheduling parallel developer agents (Pulse)
- Adversarial code review and retry loops
- Committing approved work to the feature branch

PM is only interrupted when a task gets permanently stuck or when all tasks complete.

Source: `packages/opencode/src/tasks/`
Design: `lievo/plan-v2.md` (git-ignored, local only)

End-to-end test

Before marking this phase complete, run a full end-to-end test manually:

  1. Create a real (simple) GitHub issue in randomm/opencode
  2. Run taskctl start <issueNumber> from PM
  3. Verify Composer decomposes it correctly
  4. Watch Pulse schedule a developer
  5. Verify developer implements, adversarial reviews, @ops commits
  6. Verify PM receives incremental completion notification
  7. Run taskctl status and verify it shows correctly
  8. Create PR manually with @ops after completion

Document the result (what worked, what needed adjusting) as a comment on this issue.

Acceptance criteria

  • developer-pipeline agent defined in agent/agent.ts with correct simplified prompt
  • adversarial-pipeline agent defined in agent/agent.ts with taskctl verdict instructions
  • Phases 3a/3b updated to use developer-pipeline and adversarial-pipeline agent names
  • PM system prompt updated: 10-step workflow replaced with taskctl-based workflow
  • taskctl command reference added to PM prompt
  • AGENTS.md updated with taskctl documentation section
  • End-to-end manual test completed and documented in issue comment
  • bun run typecheck passes with 0 errors across workspace (bun typecheck from repo root)

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions