# Ticket Pipeline

> Autonomous per-ticket pipeline that chains ticket-work, local-review, PR creation, test-iterate loop, CI watching, PR review loop, integration verification gate, and auto-merge into a single unattended workflow with Slack notifications and policy guardrails

- Skill: `omninode-ai/ticket-pipeline` (Agent Skill, multi-file: 3 files)
- Install (CLI): `npx skillmds@latest add omninode-ai/ticket-pipeline`
- Raw SKILL.md: https://api.skillmd.com/api/skills/omninode-ai/ticket-pipeline/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: OmniNode-ai (https://skillmd.com/u/omninode-ai)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/omninode-ai/ticket-pipeline

---


# Ticket Pipeline

## Tools Required

Workers running `ticket-pipeline` run in fresh sessions where dispatch tools are **deferred**.
If a `ticket-pipeline` worker needs to spawn sub-agents (e.g. a verifier agent), it must
fetch the schema at session start:

```
ToolSearch(query="select:Agent,SendMessage,TaskCreate,TaskUpdate,TaskGet", max_results=5)
```

Dispatch prompts from `epic-team` include this step automatically. Standalone invocations
from headless or cron contexts must include it explicitly.

**Announce at start:** "I'm using the ticket-pipeline skill."

## Usage

```
/ticket-pipeline PROJ-1234
/ticket-pipeline PROJ-1234 --dry-run
/ticket-pipeline PROJ-1234 --skip-to ci_watch
/ticket-pipeline PROJ-1234 --skip-test-iterate
/ticket-pipeline PROJ-1234 --require-gate
/ticket-pipeline PROJ-1234 --docs-only
```

## Execution

### Step 1 — Parse arguments

- `ticket_id` → Linear ticket ID (required)
- `--skip-to` → resume from phase (auto-detected from state file if omitted)
- `--dry-run` → no commits, pushes, or PRs
- `--skip-test-iterate` → skip test-fix loop (for infra-dependent tests)
- `--auto-merge` / `--require-gate` → merge policy override

### Step 2 — Initialize FSM

Primary path (bus-driven):

```bash
onex run-node node_ticket_pipeline \
  --input '{"ticket_id": "<ticket_id>", "skip_to": null, "skip_test_iterate": false, "dry_run": false}' \
  --timeout 300
```

Fallback path (local/offline):

```bash
onex node node_ticket_pipeline --input <json_file>
```

Where `<json_file>` contains `ModelPipelineStartCommand` JSON matching the payload fields above.

On non-zero exit, a `SkillRoutingError` JSON envelope is returned — surface it directly, do not produce prose. Outputs `ModelPipelineState` JSON with initial phase.

### Step 3 — Execute phases

Run each phase in sequence, advancing the FSM via `handler.advance()`. For each phase:

1. **PRE_FLIGHT**: Load ticket contract from Linear, validate repo target, check environment
2. **IMPLEMENT**: Execute ticket work (delegates to ticket-work skill)
3. **LOCAL_REVIEW**: Run local-review loop until N consecutive clean passes
4. **CREATE_PR**: Create PR via `gh pr create`, enable auto-merge
5. **TEST_ITERATE**: Fix failing tests up to `--max-test-iterations` cycles
6. **CI_WATCH**: Poll CI until green or timeout; auto-fix failures
7. **PR_REVIEW**: Address human review comments
8. **AUTO_MERGE**: Wait for merge queue; verify merged
9. **WORKTREE_CLEANUP**: Verify and remove safe per-ticket worktrees before Done

Circuit breaker halts after 3 consecutive phase failures → FAILED state.

### Step 4 — Report

Display final pipeline state: phase reached, PR URL, any errors, cycle counts.

## Phases

| Phase | FSM State | Description |
|-------|-----------|-------------|
| PRE_FLIGHT | → IMPLEMENT | Load contract, validate env |
| IMPLEMENT | → LOCAL_REVIEW | Execute ticket work |
| LOCAL_REVIEW | → CREATE_PR | Clean review passes |
| CREATE_PR | → TEST_ITERATE | Open PR |
| TEST_ITERATE | → CI_WATCH | Fix test failures |
| CI_WATCH | → PR_REVIEW | Wait for green CI |
| PR_REVIEW | → AUTO_MERGE | Address comments |
| AUTO_MERGE | → WORKTREE_CLEANUP | Merge queue |
| WORKTREE_CLEANUP | → DONE | Remove safe ticket worktrees or block with Linear note |

## Architecture

```
SKILL.md   -> thin shell (this file)
node       -> omnimarket/src/omnimarket/nodes/node_ticket_pipeline/ (FSM logic)
contract   -> node_ticket_pipeline/contract.yaml
```

