Skip to main content

Epic → task decomposition

Milestone 4 introduces the first review-first mutation workflow in A2C:

plan → propose → validate → review → apply

Given an Epic, A2C proposes a set of draft Tasks, validates them through a2c_core, lets a human review the summary and details, and only writes files after an explicit apply.

Commands

a2c plan decompose-epic <EPIC_ID>
a2c show draft-task <EPIC_ID> <INDEX>
a2c apply tasks-from-epic <EPIC_ID>

Use --path / -C when not running from the repository root.

Plan

a2c plan decompose-epic loads the Epic via a2c_core, extracts front matter and key Markdown sections (Summary, Problem, Goals, Acceptance criteria, Notes), and asks the configured provider for a structured task list.

Each proposed task includes:

  • front matter conforming to the Task schema (type, id, title, status, epic_id, …)
  • a Markdown body with at least Summary and Acceptance criteria sections

The CLI validates every draft before caching. Invalid proposals are reported with file-level reasons and are not written into planning/tasks/.

Review

After a successful plan, the CLI prints a one-line summary per draft (id, title, status, optional rationale and summary line).

Inspect a single draft:

a2c show draft-task epic-onboarding 1

Drafts are stored under .a2c/cache/decompose-epic/<epic-id>/ as Markdown files that mirror normal Task artifacts.

Apply

a2c apply tasks-from-epic loads the cached proposal, re-validates all drafts, checks for ID and filename conflicts, then writes new files under planning/tasks/ and updates the Epic task_ids list.

a2c apply tasks-from-epic epic-onboarding

Use --force only when you intentionally want to overwrite an existing task file with the same id.

Safety defaults

RuleBehaviour
No silent writesplan never touches planning/tasks/
Untrusted AI outputParsed and validated before caching or apply
ID conflictsApply fails if a task id already exists (unless --force)
Duplicate draft idsProposal fails validation
Re-run planReplaces the cached proposal; does not apply

Providers (Milestone 5)

Provider choice: CLI --provider > decomposition.provider in config > mock.

ProviderPurpose
mockDefault; deterministic output or --fixture JSON (Cursor-as-model path)
openaiHosted OpenAI-compatible API
localGeneric OpenAI-compatible endpoint (LM Studio, vLLM, gateways)
ollamaOllama preset (http://127.0.0.1:11434/v1, reachability probe)

Configuration (.a2c/config.yaml)

decomposition:
provider: mock # mock | openai | local | ollama
model: gpt-4o-mini # provider-specific
endpoint: null # local/openai override; ollama uses OLLAMA_HOST when null
timeout_seconds: 120
max_tokens: 4096
temperature: 0.2

Environment variables

ProviderVariables
openaiOPENAI_API_KEY (required), OPENAI_BASE_URL, OPENAI_MODEL (optional)
localA2C_LOCAL_LLM_ENDPOINT (required if config endpoint unset), LOCAL_LLM_MODEL, LOCAL_LLM_API_KEY (optional)
ollamaOLLAMA_HOST (optional, default http://127.0.0.1:11434), OLLAMA_MODEL, OLLAMA_API_KEY (optional)

Examples

# Default mock (no API keys)
a2c plan decompose-epic epic-onboarding
a2c plan decompose-epic epic-onboarding --fixture path/to/response.json

# Hosted OpenAI
a2c plan decompose-epic epic-onboarding --provider openai

# Local OpenAI-compatible server
a2c plan decompose-epic epic-onboarding --provider local --endpoint http://localhost:8080/v1 --model llama3.2

# Ollama preset (assumes default listen address; not OS auto-discovery)
a2c plan decompose-epic epic-onboarding --provider ollama --model llama3.2

Provider failures are actionable and never write to planning/. The CLI does not silently fall back to mock when a real provider is selected.

Future: native Ollama SDK via optional a2c-core[ollama] — see pathname:///a2c-assets/plans/milestone-ollama-native-sdk.md.

Optional live Ollama smoke on a self-hosted GPU runner: testing-ollama-ci.md.

Package boundaries

LayerResponsibility
a2c_coreParsing, validation, proposal cache, apply writes
a2c_cliProvider selection, human output, exit codes

a2c_core does not depend on a2c_cli.

Limitations

  • One Epic per command; no batch decomposition.
  • Task drafts only — no Sprint creation or assignment.
  • No automatic owner/assignee fields.
  • No interactive TUI or editor integration yet.