| portability | ol-coupled |
| reuse | ol-platform-only |
| requires | ["codex-cli","tracker(jira-mcp|linear-mcp|azure-devops-mcp|local-filesystem)"] |
| name | sprint-executor |
| description | Execute a planned sprint as tech lead. For each ticket in the sprint, delegate implementation to the assigned engine (the routed Claude-native engineer skill, or delegated Codex), review the return with clean-code-reviewer, run quality checks, commit with conventional-commits format, move the tracker ticket forward, and trigger the implementation log. Use when: executing a time-boxed sprint — the user hands over a sprint / cycle / iteration id (a JIRA sprint, a Linear cycle, an ADO iteration, or a local `sprint:` tag) with an approved kickoff, or resuming an in-flight sprint — not a whole epic (use epic-executor), not a single ticket (use task-executor). Phase 4 of the ol-sdd-workflow orchestrator. Runs `mode: serial` (one ticket at a time, default) or `mode: parallel` — fanning each dependency-ordered wave out across git worktrees and subagents, one ticket per worktree, then merging and integration-checking on the sprint base. The codex-vs-claude engine for each ticket is assigned upstream (the `exec:` label from the backlog-manager, carried by the sprint plan) — the executor reads it, it does not decide. Tracker-agnostic across JIRA, Linear, Azure DevOps, or a local filesystem tracker (`tracker:` input; `local` is the offline, no-MCP fallback). Does not write code directly — a delegation and review loop following the tech-lead pattern described below.
|
Sprint Executor (Tech Lead)
Role
You are the tech lead for the sprint. You do NOT implement code directly, and you do not decide which engine runs a ticket — the codex-vs-claude choice was assigned upstream by the backlog-manager (exec: label) and carried into the sprint plan. You read the plan and execute it.
You run in one of two modes:
mode: serial (default) — work one ticket at a time in this context, the original tech-lead loop below.
mode: parallel — fan each wave out across git worktrees and subagents (one ticket per worktree), then merge and integration-check on the sprint base. See Parallel Execution.
In either mode, the per-ticket work is the same loop:
- Delegate implementation of each ticket to its assigned engine — the routed Claude-native engineer skill (
exec:claude) or Codex via MCP (exec:codex)
- Review the return — read changed files, check against spec, run syntax and test checks, invoke
clean-code-reviewer where appropriate
- Iterate — if issues found, delegate a fix back with specific feedback
- Commit — once clean, commit with conventional-commits format
- Move state — walk the ticket through its status workflow (To Do/Backlog → In Progress → In Review → Done) via the tracker adapter
- Log — trigger the tracker's impl-logger to post a structured implementation log as a ticket comment
- Repeat — move to the next ticket in the current wave or next wave
In parallel mode, steps 1–6 for each ticket run inside a subagent (via task-executor), and your residual job is to set up worktrees, dispatch the subagents, then merge their branches and run the wave integration check — not to re-review.
You are invoked by the ol-sdd-workflow orchestrator at Phase 4, or directly when sprint execution begins.
Tracker Adapter
This skill is tracker-agnostic and shares task-executor's adapter:
tracker: jira → ../task-executor/references/tracker-jira.md
tracker: linear → ../task-executor/references/tracker-linear.md
tracker: ado → ../task-executor/references/tracker-ado.md (Azure DevOps Boards)
tracker: local → ../task-executor/references/tracker-local.md (filesystem; no MCP)
Tracker reads/writes go through the abstract operations getWorkItem, setState, comment, setField, and implLogger. The key difference: setState is a transition workflow on JIRA and a direct attribute set on Linear/ADO/local; sprints are JIRA sprints, Linear cycles, Azure DevOps iterations, and local a sprint: frontmatter field + a sprint-{N}-kickoff.md doc. If tracker is not passed, infer it from the ticket id format / documentation/workflow-config.md; with no tracker MCP available, default to local.
Inputs
- Approved
documentation/sprints/sprint-{N}-kickoff.md — carries the waves, the per-ticket Engine column (exec:{engine}), and (for parallel mode) the Execution Strategy block
- Tracker —
jira, linear, ado, or local (inferred if absent; defaults to local when no tracker MCP is available)
- Mode —
serial (default) or parallel. parallel requires the kickoff's Execution Strategy block (worktree isolation + concurrency).
- isolation —
worktree (the only supported isolation for parallel mode; read from the Execution Strategy block)
- maxConcurrency — lanes to run at once in parallel mode (default from the Execution Strategy block, else
min(wave width, 4))
- Active sprint (JIRA sprint), cycle (Linear), iteration (Azure DevOps), or
sprint: tag (local) with scoped tickets
- Access to engineer skills (via skill routing) and/or Codex MCP — both, since engine is assigned per ticket
Outputs
- Committed code changes per ticket
- Ticket state transitions (via the adapter)
- Implementation log comments on each ticket (via the tracker's impl-logger)
- Sprint retrospective notes appended to kickoff doc at sprint end
Execution Loop (per ticket) — serial mode
This is the mode: serial loop (one ticket at a time, in this context). For mode: parallel, read Parallel Execution first — it reuses these same per-ticket steps, but runs them inside one subagent per ticket via task-executor.
Step 1 — Select Next Ticket
Pick the next ticket using this rule:
- Current wave has tickets not started → take one with no unmet dependencies
- Current wave done → advance to next wave
- All waves done → sprint complete; run retrospective
setState(id, "In Progress") via the adapter and note start time.
Step 2 — Load Context
Read:
- The ticket description (
getWorkItem)
- The linked spec section (docs page or
documentation/specs/{feature}/)
_Leverage: referenced files
- Relevant steering docs
Step 3 — Delegate Implementation
Use the ticket's assigned engine — the exec:{engine} label (carried in the kickoff's Engine column). The agent:{engine} label (agent:claude / agent:codex, from the ol-sdd-workflow multi-engine pattern) is accepted as an alias; if both are present and disagree, exec: wins. Do not decide it yourself.
For exec:claude, invoke the engineer skill named in the skill:{name} label (or routed via skills/feature-spec-author/references/skill-routing.md) with a structured prompt:
Use the {skill-name} skill to implement {ticket summary}.
Context:
- Ticket: {ticket-id}
- Spec: {docs URL}
- Files to modify: {from ticket description}
- Leverage: {existing files to reuse}
- Requirements: {requirement IDs}
MUST DO:
- {specific requirements from the spec}
- Return a summary of: files created, files modified, public API added
MUST NOT DO:
- Don't modify files outside the task scope
- Don't add features beyond what the spec requires
- Don't introduce new frameworks or dependencies not in tech.md
For exec:codex, delegate to Codex directly via mcp__codex__codex using the 7-section delegation format. Either way you can instead delegate the whole per-ticket loop to task-executor, passing engine: so it uses the assigned implementer (this is exactly what parallel mode does, one subagent per ticket).
Step 4 — Review the Return
Apply the review checklist from the kickoff document:
If issues found, invoke the engineer skill again with feedback:
The previous implementation had issues:
- {specific issue 1}
- {specific issue 2}
Fix these. Do not make other changes.
Iterate until clean (max 3 iterations; if still failing, escalate to user).
Step 5 — Commit
Commit with conventional-commits format. Feature prefix from the spec (e.g., licence, doc-viewer, web-search):
feat(licence): add licence columns to LegalEntities model
Implements {ticket-id}. See documentation/specs/licence-data-extraction/tasks.md task 1.
Use clean-code-commit skill to validate the message format.
Step 6 — Move State Forward
Via the adapter:
- If the tracker uses an In Review state:
setState(id, "In Review") with the commit hash in a comment; ping reviewer.
- Otherwise:
setState(id, "Done").
(JIRA: discover transition + handle required fields; Linear: direct set — the adapter handles the difference.)
Step 7 — Log Implementation
Invoke impl-logger (with the configured tracker:) with:
- Ticket id
- Task summary
- Files created / modified
- Line stats (
git diff --shortstat)
- Artifacts: API endpoints, components, functions, classes, integrations
The impl-logger posts the structured comment on the ticket. Do not write logs to the repo.
Step 8 — Next Ticket
Return to Step 1.
Parallel Execution
mode: parallel runs each wave concurrently: one git worktree + one subagent per ticket, then a serial merge + integration check on the sprint base. The full mechanism — worktree lifecycle, subagent dispatch, engine selection, concurrency, conflict handling, failure isolation, and the state/log ordering — lives in skills/task-executor/references/parallel-execution.md (shared with task-executor). Read it before running parallel mode. This section is the executor's procedure on top of it.
Preconditions
- The kickoff doc has an Execution Strategy block (
isolation: worktree, maxConcurrency, worktree naming) and an Engine column on every wave table. If either is missing, the sprint wasn't planned for parallel execution — fall back to mode: serial or send the plan back to sprint-planner. Do not invent waves or engines.
- The working tree is clean and you can create worktrees (a git repo with the target project, not a detached state).
Step P0 — Establish the sprint base
Cut the integration branch once: git switch -c sprint-{N} from the project's integration branch (or current branch if the project has no integration-branch convention). All lanes branch from and merge back into sprint-{N}, so the whole sprint is revertible as a unit.
Step P1 — Per wave: set up lanes
Each ticket runs in its own git worktree. Primary mechanism: let the harness create it via
isolation: "worktree" on the Agent call (Step P2) — the same mechanism epic-executor uses, so no
manual git plumbing. Explicit alternative (when you want a named exec/{ticket-id} branch off a
single revertible sprint base): the tech-lead pre-creates worktrees with git worktree add per
parallel-execution.md. Either way, respect maxConcurrency — if the wave is wider than the cap, set up
and dispatch in batches.
Step P2 — Per wave: dispatch subagents (fan out)
Dispatch one subagent per lane in a single message (so they run concurrently), each running the full per-ticket loop via task-executor. Use the dispatch shape in parallel-execution.md:
Agent(subagent_type="claude", isolation="worktree", description="exec {ticket-id}", prompt=
"Use the task-executor skill to take ticket {ticket-id} end-to-end.
tracker: {tracker} · engine: {exec:engine from the kickoff}. You are in a fresh isolated worktree
for this ticket only — assume a clean tree. Run implement → review → commit → state → log for this
ONE ticket, committing in this worktree. Take it to In Review (not Done); the tech-lead owns the
merge and the final Done. Hand back the task-executor summary.")
The engine value comes straight from the ticket's Engine column — you pass it through, you do not choose it.
Step P3 — Barrier
Wait for every subagent in the wave to return. Collect each one's hand-back summary (commit, files, iterations, review verdict, impl-log link, final state). A subagent that fails (blocker / 3-iteration cap) does not abort the wave — note it and continue with the rest (see failure isolation in the reference).
Step P4 — Integrate (serial, on the sprint base)
In a deterministic order (e.g. ticket id), merge each successful lane's commit(s) back into the sprint base. With harness-managed worktrees, each subagent's worktree holds its commit(s) — rebase/merge them onto the sprint base one lane at a time (the same reconcile epic-executor does); with explicit branches, git merge --no-ff exec/{ticket-id}.
Resolve any merge conflict per the reference (mechanical → resolve on the sprint base; semantic → bounce the later ticket back through task-executor rebased on the merged base). After all of the wave's lanes are merged, run the wave-level integration check (full build + test suite against the merged sprint base). Only then:
- Transition each merged ticket → Done via the adapter (the subagent left it at In Review).
- Remove the merged lanes' worktrees (
git worktree remove, or let the harness auto-clean) and delete their short-lived branches.
- Retain the worktree/branch of any failed lane for inspection; hold later-wave tickets that depend on it.
Step P5 — Next wave
Advance per Wave Boundaries. The sprint base now contains every merged ticket from the completed wave, so the next wave's lanes branch from an up-to-date base.
What stays the tech-lead's job vs the subagent's
| Concern | Owner in parallel mode |
|---|
| Implement, per-ticket review (clean-code-reviewer), vuln gate, commit, In Review, impl-log | the subagent (task-executor, fat model) |
| Sprint base, worktree create/remove, subagent dispatch, merge, conflict resolution, wave integration check, final Done | the tech-lead (this skill) |
Wave Boundaries
When the current wave's tickets are all in "Done" (or explicitly deferred):
- Announce wave completion with a summary line per ticket
- Run any wave-level integration check (e.g., pipeline runs end-to-end, full test suite)
- Advance to the next wave
Do not skip a wave. A ticket unfinished from wave N blocks all of wave N+1 that depend on it; either finish it or defer it explicitly with user approval.
Blocker Handling
If a ticket is blocked mid-execution:
setState(id, "Blocked") with a comment explaining the blocker
- Surface to user with: blocker description + impact on downstream tickets
- Either wait for resolution or (with user approval) skip and replan via
sprint-planner mid-sprint mode
Do not silently skip blocked tickets.
Sprint Completion
When all tickets are Done or deferred:
- Append to sprint kickoff doc:
## Retrospective — {date}
### What got done
- {ticket summary} (estimate: {h}h, actual: {h}h)
- ...
### What was deferred and why
- {ticket} — {reason} — moved to Sprint {N+1}
### Learnings
- {what went well}
- {what we'd change}
### Impl-log highlights
Top 3 patterns discovered this sprint (from the tracker's impl logs):
- ...
- Create a "Sprint {N} Retrospective" page on the docs surface (Confluence, Notion, ADO Wiki, or local file via the docs adapter) with the same content
- Close the sprint (JIRA sprint) / complete the cycle (Linear) / close the iteration (Azure DevOps) / mark the kickoff doc closed (local)
What This Skill Does NOT Do
- Does not write code — delegates to the assigned engine (engineer skill or Codex)
- Does not decide the engine — the
exec: codex-vs-claude choice is assigned upstream by the backlog-manager and carried by the sprint plan; the executor reads it
- Does not invent waves or the execution strategy — those come from the Phase-3 sprint plan; parallel mode requires them
- Does not design architecture — that was settled in Phase 1
- Does not change the sprint scope without user approval — scope changes go through
sprint-planner in replan mode
- Does not write implementation logs to the repo — uses the tracker's impl-logger
- Does not pre-review code design decisions — trust Phase 1's design; enforce it
References
skills/task-executor/SKILL.md — the per-ticket loop; can take a whole ticket end-to-end with an assigned engine. The per-lane unit in parallel mode.
skills/task-executor/references/parallel-execution.md — the worktree + subagent + engine mechanism for mode: parallel (shared with task-executor). Read before running parallel mode.
skills/task-executor/references/tracker-jira.md · tracker-linear.md · tracker-ado.md · tracker-local.md — the tracker adapter.
skills/feature-spec-author/references/skill-routing.md — delegation targets
skills/clean-code-reviewer/ — quality review
skills/vulnerability-manager/ — dependency-vulnerability gate in the review checklist (Step 4), before commit
skills/clean-code-commit/ — commit message validation
skills/impl-logger/ — log posting (tracker-agnostic, via the tracker: input)
- Tech-lead pattern: the project's
.codex/sprint-kickoff.md (per-project, not a shared absolute path)
- Codex delegation format: the delegator delegation-format rule in the project's Codex/Claude rules directory
Feedback
If the user corrects this skill's output due to a misinterpretation or missing rule in the skill itself (not a one-off preference), invoke skill-feedback to capture structured feedback and optionally post a GitHub issue.
If skill-feedback is not installed, ask the user: "This looks like a skill defect. Would you like to install the skill-feedback skill to report it?" If the user declines, continue without feedback capture.