@turkit/workflow
Version:
Project-agnostic workflow Agent Skills (ticket lifecycle, reviews, ship, handoff) distributed via TanStack Intent.
147 lines (102 loc) • 7.13 kB
Markdown
---
name: ticket-triage
description: Entry point for any ticket. Fetches the issue (if a tracker is available), evaluates scope, picks the path (one-shot / plan-then-execute / split-first), and dispatches the next skill in the same session. Only plan-then-execute requires a fresh session for execution.
---
# Ticket Triage
Route a ticket toward the right workflow **and dispatch it in the same session**.
- **one-shot** → triage writes a minimal plan then auto-invokes `ticket-execute` here and now.
- **plan-then-execute** → triage auto-invokes `ticket-plan` here and now. `ticket-plan` ends by printing a fresh-session prompt for `ticket-execute`. Operator runs that in a new session.
- **split-first** → triage writes a split proposal and stops. No implementation.
## Format de sortie obligatoire — LIS CECI EN PREMIER
Triage est un dispatcher. Sa sortie n'est **jamais** un résumé du travail à venir — c'est soit le bloc de sortie du skill dispatché (one-shot / plan-then-execute), soit le bloc strict de split-first.
### Pour `one-shot` et `plan-then-execute`
Le dernier bloc visible à l'opérateur est celui émis par `ticket-execute` (handoff) ou `ticket-plan` (fresh-session prompt). **Triage n'ajoute rien après.** Pas de récap, pas de "scope walkbacks resolved", pas de "architecture summary", pas de "ready for review". Le triage report (étape 4) sort avant le dispatch ; ensuite tu laisses le skill dispatché parler en dernier.
### Pour `split-first`
Le dernier message est **exactement** ce bloc, et **rien d'autre après** :
````
✅ Split proposé — `.claude/plans/<TICKET-ID>-split.md`
Prochaine action — crée les sous-tickets dans le tracker, puis re-triage chacun avec ce prompt :
```
/turkit-workflow:ticket-triage <SOUS-TICKET-ID>
```
````
Pas de résumé du split dans le chat — le fichier parle de lui-même. Une seule fence interne, copy/paste en un clic.
### Anti-pattern observé (NE JAMAIS reproduire)
Tu viens de dispatcher `ticket-plan` et tu vas avoir envie de résumer le plan que ton sous-skill vient d'écrire. Ne le fais pas. Voici exactement le type d'output qui a déjà cassé ce skill en prod après dispatch et qui ne doit jamais revenir :
> Plan written to .claude/plans/SUP-28.md.
> Triage decision: plan-then-execute.
> Plan summary (10 ACs):
> - Append a second SettingsItem ("Delete my account")…
> - Build DeleteAccountWarning.tsx…
> - …
> Key walkback decisions: …
> Risks flagged: …
> Ready for operator review. Next step is ticket-execute once you approve.
Quatre violations :
1. **Résume le plan** au lieu de pointer vers le fichier que `ticket-plan` vient d'écrire.
2. **Ne propose aucun prompt copy/paste** pour la nouvelle session — `ticket-plan` est censé l'avoir fait, et si tu ajoutes ce narratif derrière, tu détruis son bloc copiable.
3. **Finit par une phrase** ("Ready for operator review…") au lieu de laisser la fence interne du sous-skill en dernier.
4. **Propose une condition** ("once you approve") au lieu d'une action directe et copiable.
Ton output correct après dispatch est exactement ce qu'a émis le sous-skill, point. Tu ne touches à rien après.
## Steps
1. **Resolve the ticket.**
- Accept an explicit ticket ID as argument, **or**
- Detect via `docs/contracts/issue-tracker-detection.md`.
- If no tracker is available, ask the operator for the ticket ID or a short description of the work.
2. **Fetch issue context** if a tracker is available. Read title + body. If not, use the operator-provided description.
3. **Scope the work** and pick one of three paths. Use these heuristics:
| Path | Signals |
|---|---|
| **one-shot** | < 1 hour. One well-understood change. Single file or tight cluster. Clear acceptance criteria. |
| **plan-then-execute** | 1 hour – 1 day. Multiple files / modules. Some design decisions to make. Tests need thought. |
| **split-first** | Multi-day. Cuts across unrelated subsystems. Mixes infra + product + tests. Multiple operator reviews needed. |
If between two options, prefer the heavier one. Operator can downgrade.
4. **Emit the triage report** (block below), then dispatch.
```
Ticket : <TICKET-ID> — <short title>
Path : <one-shot | plan-then-execute | split-first>
Reason : <1–2 sentences>
```
5. **Dispatch** based on path. The fresh-session boundary lives **only** between `ticket-plan` and `ticket-execute`. Triage never asks the operator to start a new session for `ticket-plan` and never prints a copy-paste prompt for the next skill — it invokes it.
- **one-shot** → write a minimal plan to `.claude/plans/<TICKET-ID>.md` (template below), then **invoke `ticket-execute` via the Skill tool in this same session**. Tu n'ajoutes rien après le retour du sous-skill — son handoff block est le dernier message.
- **plan-then-execute** → **invoke `ticket-plan` via the Skill tool in this same session**. `ticket-plan` writes the plan AND emits the fresh-session prompt. Tu n'ajoutes rien après son retour — son bloc fence est le dernier message. Pas de résumé du plan, pas de récap des ACs, pas de "scope walkbacks resolved".
- **split-first** → write the split proposal to `.claude/plans/<TICKET-ID>-split.md` (template below), then émets le bloc de split-first défini en haut, puis arrête.
## One-shot minimal plan template
Write to `.claude/plans/<TICKET-ID>.md` before invoking `ticket-execute`:
```markdown
# <TICKET-ID> — <short title>
## Context
<1–2 sentences>
## Acceptance criteria
- [ ] <criterion 1>
- [ ] <criterion 2 if needed>
## Approach
<2–4 lines. One-shot scope means design is obvious.>
## Files to touch
- Modify: `path/to/file` — <change>
## Quality contract
- Reuse: <existing helper/module to use, or "none">
- Ownership: <where new code lives if any>
- Verification: <project check/lint/test command(s)>
```
## Split-first proposal template
Write to `.claude/plans/<TICKET-ID>-split.md`:
```markdown
# <TICKET-ID> — Split proposal
## Reason for split
<why the ticket can't merge as one unit>
## Proposed sub-tickets
### <TICKET-ID>.1 — <title>
Scope: ...
Acceptance criteria:
1. ...
### <TICKET-ID>.2 — <title>
...
```
## Guardrails
- Never invoke any review skill (`pre-commit-review`, `pre-pr-review`, `ship`, `test-instructions`).
- Split-first never auto-invokes anything.
- **`one-shot` and `plan-then-execute` always auto-invoke the next skill in the same session.** Printing a copy-paste prompt like "`/turkit-workflow:ticket-plan SUP-14`" instead of invoking the skill is a bug — it breaks the workflow by forcing an unnecessary session boundary on the operator.
- **After dispatching `ticket-plan` or `ticket-execute`, add nothing.** Voir la section "Format de sortie obligatoire" en haut et l'anti-pattern qui suit. La dernière fence interne de la conversation doit être un copy/paste propre en un clic, émise par le sous-skill.
- If the ticket body is missing or trivially short, ask the operator to flesh it out before choosing a path.
- Respond in the conversation's language by default.