Skip to content

Tactical agent

flowchart LR
  Triggers@{ shape: bolt, label: "Triggers" }
  TacticalAgent["Tactical agent"]
  Issue@{ shape: notch-rect, label: "Issue
type: Feature" }
  Tasks@{ shape: processes, label: "Tasks" }

  Triggers --triggers--> TacticalAgent
  TacticalAgent -- edits --> Issue
  TacticalAgent -- creates --> Tasks

  class Triggers triggersOrange
  class TacticalAgent tacticalPink

  classDef triggersOrange fill:#ffe8d4,stroke:#d66a28,color:#d66a28
  classDef tacticalPink fill:#f8d4e4,stroke:#e55398,color:#e55398

The Tactical agent reads a designed feature issue and produces a tactical plan: numbered task issues with acceptance criteria, a YAML wave structure, and a feature branch. It turns “here’s the spec” into “here’s exactly what to build, in what order.”

Type: LLM (Claude)
Script: .autoducks/agents/tactical/pre.sh + post.sh

EventCondition
Issue comment/agents devise
Issue comment/agents execute on a Feature issue without the Ready label (auto-escalation)
Pre-execution
  1. Reacts to the trigger comment with 👀.
  2. Fetches the issue content and writes it to /tmp/issue-request.md.
  3. Revision detection: if the issue already has the Ready label, this is a plan revision. The agent extracts existing task numbers from the YAML block and builds revision context (prior plan + recent comments).
LLM execution

The agent reads the issue spec (and revision context if applicable) and produces:

Option A — a plan written to /tmp/plan-body.md, with a ## Tasks section containing task entries in the format:

### T1 — Title
**Summary:** What this task does.
**Tasks:**
- [ ] Specific implementation step
**AcceptanceCriteria:**
- [ ] Testable criterion

Option B — questions written to /tmp/questions.md if critical information is missing to produce a good plan.

Post-execution
  1. Questions mode: posts questions as a comment and exits (waits for human clarification).
  2. Parse the plan: parse-plan.py extracts tasks from the ## Tasks section, validates structure, and produces /tmp/tasks.jsonl. On parse failure: posts error as comment and exits.
  3. Reconcile tasks: creates new task issues, updates existing ones if changed, closes dropped tasks. Maps T1/T2 placeholders to real issue numbers.
  4. Replaces T1/T2 placeholders in the plan body with real issue numbers. Strips the ## Tasks section (tasks are now separate issues). Updates the feature issue body.
  5. First pass only (not revision): adds Ready label, sets issue type to Feature, creates feature branch feature/{id}-{slug}, creates a draft PR targeting main, assigns the commenter.
  6. Reacts with 👍 and posts a comment listing created tasks with a suggestion to run /agents execute.
  • Task issues created as children of the feature issue, each with type Task
  • Feature issue body updated with wave structure (YAML block) and task references
  • Ready label added to the feature issue
  • Feature branch created: feature/{id}-{slug}
  • Draft PR created targeting main (first pass only)

The tactical plan embeds a YAML block in the feature issue body that the Wave Orchestrator uses:

waves:
- tasks: [101, 102] # Wave 1: parallel tasks
- tasks: [103] # Wave 2: depends on Wave 1
- tasks: [104, 105] # Wave 3: depends on Wave 2

Tasks in the same wave run in parallel. Each wave starts only after the previous wave is fully done (all task PRs merged).

permissions:
contents: write
issues: write
pull-requests: write
id-token: write
/agents devise --model claude-opus-4-7
ArgumentDefaultDescription
--modelFrom .autoducks/autoducks.jsonClaude model to use
--reasoningFrom .autoducks/autoducks.jsonReasoning effort