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
Triggers
Section titled “Triggers”| Event | Condition |
|---|---|
| Issue comment | /agents devise |
| Issue comment | /agents execute on a Feature issue without the Ready label (auto-escalation) |
Behavior
Section titled “Behavior”Pre-execution
- Reacts to the trigger comment with 👀.
- Fetches the issue content and writes it to
/tmp/issue-request.md. - Revision detection: if the issue already has the
Readylabel, 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 criterionOption B — questions written to /tmp/questions.md if critical information is missing to produce a good plan.
Post-execution
- Questions mode: posts questions as a comment and exits (waits for human clarification).
- Parse the plan:
parse-plan.pyextracts tasks from the## Taskssection, validates structure, and produces/tmp/tasks.jsonl. On parse failure: posts error as comment and exits. - Reconcile tasks: creates new task issues, updates existing ones if changed, closes dropped tasks. Maps
T1/T2placeholders to real issue numbers. - Replaces
T1/T2placeholders in the plan body with real issue numbers. Strips the## Taskssection (tasks are now separate issues). Updates the feature issue body. - First pass only (not revision): adds
Readylabel, sets issue type toFeature, creates feature branchfeature/{id}-{slug}, creates a draft PR targetingmain, assigns the commenter. - Reacts with 👍 and posts a comment listing created tasks with a suggestion to run
/agents execute.
Output
Section titled “Output”- 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
Readylabel added to the feature issue- Feature branch created:
feature/{id}-{slug} - Draft PR created targeting
main(first pass only)
Wave structure
Section titled “Wave structure”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 2Tasks in the same wave run in parallel. Each wave starts only after the previous wave is fully done (all task PRs merged).
Required permissions
Section titled “Required permissions”permissions: contents: write issues: write pull-requests: write id-token: writeDirective arguments
Section titled “Directive arguments”/agents devise --model claude-opus-4-7| Argument | Default | Description |
|---|---|---|
--model | From .autoducks/autoducks.json | Claude model to use |
--reasoning | From .autoducks/autoducks.json | Reasoning effort |