ds-ticket-triage
Purpose: Strategic triage command that takes a ticket list or tracker input,
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Purpose: Strategic triage command that takes a ticket list or tracker input,
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
SOC 職業分類に基づく
Apply when the user mentions any software development work: implementing features, fixing bugs, reviewing or refactoring code, debugging, testing, deploying, working with agents or subagents, making architecture decisions, setting up projects, managing dependencies, writing scripts, or any task that involves reading, writing, or reasoning about code and systems.
Agentic Engineering Protocol for Hermes - structured delegation model, risk classification, adversarial review loops, code quality gates, git workflow conventions, and named agent definitions. Load this skill when doing AI-assisted software development with Hermes Agent.
Apply when the user mentions any software development work: implementing features, fixing bugs, reviewing or refactoring code, debugging, testing, deploying, working with agents or subagents, making architecture decisions, setting up projects, managing dependencies, writing scripts, or any task that involves reading, writing, or reasoning about code and systems.
Pre-implementation technical design agent. Spawn when you need a structured technical plan before writing code. Reads the codebase, identifies patterns and constraints, evaluates approaches, and produces a concrete plan a Worker can execute directly. Never writes or modifies files.
General-purpose implementation agent. Spawn for any code change: new features, bug fixes, refactors, configuration changes, or script writing. Reads the codebase to understand conventions, implements the change, runs quality gates, and returns a clear summary of what was done. This is the standard Worker for all Elevated-risk implementation tasks.
Cheap per-turn stop-condition check for open-goal loops. Spawned by the conductor ONLY after an Elevated iteration produces a clean Skeptic sign-off, to evaluate the operator-declared goal_condition and return continue-vs-stop only - never for a Low/Trivial iteration (no Skeptic sign-off exists to run after; the conductor evaluates goal_condition directly there instead). Tier 1 (haiku) leaf agent - read-only, no subagent spawning, never runs in place of, before, or concurrently with a Skeptic review. Does NOT review correctness or safety and does NOT raise, waive, or comment on Skeptic findings. Returns BLOCKED only as a structural guard when spawned without a confirmed Skeptic sign-off; the conductor handles this BLOCKED as a fallback to direct evaluation, NOT as the generic Worker-BLOCKED-means-cap_reached-escalation semantics in content/references/subagent-protocol.md - a BLOCKED return here never halts the loop. On any other failure (unavailable, errored, timeout, malformed output) the conductor falls bac
| name | ds-ticket-triage |
| description | Purpose: Strategic triage command that takes a ticket list or tracker input, |
| user-invocable | true |
Run the Activation preflight from
METHODOLOGY.mdbefore proceeding. If inactive, no-op and exit.
Strategic triage for a set of tickets. Produces a lane-distributed game plan with paste-ready /ds-implement-ticket kickoff prompts. Stops at the plan; does not invoke /ds-implement-ticket, touch the tracker, or write any .agentic/ state.
/ds-ticket-triage - (no args) resolve the operator's open assigned tickets from the configured tracker and triage them. Requires TRACKER != none; see Phase 0 no-args behavior below./ds-ticket-triage <input> - triage the ticket set, distribute across 3 lanes (default)./ds-ticket-triage --lanes <N> <input> - override the lane cap.<input> accepts any form that /ds-implement-ticket Phase 0 accepts: bare ticket IDs, comma/space-separated lists, Jira/Linear URLs, JQL search URLs, pasted screenshots, or any mixture.TRACKER == none, skip Phase 1 metadata fetch; run Phase 2a on structural links only (none available) and Phase 2b at Level 1 only (no components/labels); print "No tracker configured - heuristic-only analysis, no metadata." before Phase 1.Run the activation preflight (see METHODOLOGY.md). If inactive, no-op and exit.
Resolve TRACKER, TICKET_PREFIX, and JIRA_BASE_URL using the SAME resolution chain as /ds-implement-ticket Setup (AGENTS.md ## Tracker / ## Linear sections). Cache results in-context for the session; do not re-resolve mid-command.
No-args default (invoked with no <input> argument).
When /ds-ticket-triage is invoked with no input, resolve the operator's open assigned tickets from the configured tracker (read-only query; no tracker writes):
TRACKER == none: print "No tracker configured - an explicit ticket list or URL is required when no tracker is connected." and exit.project = <TICKET_PREFIX> AND assignee = currentUser() AND statusCategory != Done ORDER BY priority DESC in the configured project using mcp__mcp-atlassian__jira_search, where <TICKET_PREFIX> is the project key resolved by the Preflight. Use the same pagination cap (50 results) as Phase 0's JQL resolver. Collect entries as {ticket_id, source: "assigned"}.assignee: me, team = the resolved team (from Team/TICKET_PREFIX in the tracker resolution), and state type not in (completed, canceled) using mcp__linear__list_issues. Collect entries as {ticket_id, source: "assigned"}.[phase: ticket-triage | phase=resolve-assigned]
Explicit input (any <input> argument provided).
Reuse /ds-implement-ticket Phase 0 by reference - invoke the same normalization logic verbatim without forking or copying the classifier table. Output is the in-memory normalized_input.entries[] list.
No .agentic/ state writes. Phase 0 here is read-only: do NOT invoke Phase 0a-pre, Phase 0a, or any batch-state / loop-state write that implement-ticket's Phase 0 may chain into. Normalization only.
Large-list gate: if len(entries) > 20, prompt: "Ticket count exceeds 20 - investigator pass will be skipped (HEURISTIC_ONLY=true). Conflict analysis will be Level 1 only (component/label overlap). Continue? [y/N]". On y: set HEURISTIC_ONLY=true and proceed. On n: exit.
[phase: ticket-triage | phase=normalize]
Conductor-direct (no subagent). For each entry in normalized_input.entries[], fetch:
mcp__mcp-atlassian__jira_get_issue - capture priority, status, story_points (or timeestimate), labels, components, assignee, and issuelinks (blocks / is-blocked-by / relates-to).mcp__linear__get_issue - capture priority, state, estimate, labels, assignee, and relations (blocks / blocked-by / related).The captured estimate (story_points / timeestimate / Linear estimate) populates the display-only "Est" column in the Phase 4a per-ticket summary table; no distribution rule consumes it, and estimate-aware lane sizing is a deferred default. Only story_points and Linear estimate trigger the story-size preflight below - timeestimate is Jira's time-tracking field (denominated in seconds), display-only, and is never compared against the preflight threshold.
Soft-fail per ticket: on any fetch error, mark fetch_failed: true on that entry and proceed. Fetch-failed tickets are treated as independent (no known deps, no known metadata) in all downstream phases.
Terminal-status detection: tickets whose status maps to a Done/Cancelled/Won't-do state are marked terminal: true. They are added to the deferred set in Phase 3 Rule 1 without further analysis.
In-progress detection: tickets whose status maps to an active/started/in-progress workflow state are marked in_progress: true. They are carried through Phase 2 analysis but removed from lane assignment after Rule 1 (shown badged [IN PROGRESS] in the artifact; excluded from kickoff prompts).
Story-size preflight - runs once, immediately after all metadata is collected.
For each ticket whose estimate is available (
story_pointsor Linearestimateis a number) AND that is notterminal: trueorin_progress: true(those are deferred / excluded from lane assignment regardless of size - warning them here would flag tickets that never reach/ds-implement-ticket), check:
≥ 5 points: print the following warning (once per oversized ticket):
⚠ [DS-XX] Est: N pts - large story. Recommend decomposing into ≤ 3-point sub-tickets before running /ds-implement-ticket. A single 5+ point story can exhaust the context window before the loop completes. Split strategy: one sub-ticket per independent deliverable; use /ds-ticket-triage on the sub-set to re-sequence.Then append a
context_risk: highflag to that entry. Lane assignment proceeds normally; the operator decides whether to decompose.3-4 points: no warning.
context_riskis unset.≤ 2 points or estimate absent: no warning. Safe to run as-is.
Token-reduction reminder - if any ticket has
context_risk: high, append this one-time callout at the end of the story-size preflight output:💡 Token-reduction tools: if your harness supports ctx_* context-mode tools (ctx_execute, ctx_batch_execute), prefer them over raw shell output for any operation producing > 20 lines - they reduce context consumption by ~98% (see content/rules/code-standards.md §Context Window Management). If context fills mid-session, /ds-wrap → /clear → re-invoke /ds-implement-ticket with the remaining ticket IDs to continue in a fresh window.Silent on clean sets: if no ticket has
context_risk: high, print nothing. No output on safe sessions.The
context_riskflags are display-only; no distribution rule consumes them.
[phase: ticket-triage | phase=metadata]
From the blocks / is-blocked-by link fields, build a directed acyclic graph over the ticket set. Links pointing to tickets outside the set are recorded as external_deps[] (noted in the artifact but not used for lane assignment).
Cycle detection: if a cycle is found, break it at the lowest-confidence link (relates-to < blocks < is-blocked-by). Defer both endpoints with cycle_warning: true. Do not abort - continue with the remaining graph.
[phase: ticket-triage | phase=dag]
Level 1 (always, conductor-direct): for each pair of tickets, check for shared components[] or labels[]. Mark any overlapping pair as in the same conflict group. Functional-duplicate detection is NOT performed at Level 1 (no ticket content is read).
Level 2 (when !HEURISTIC_ONLY and len(entries) <= 20): spawn one background investigator over all tickets. The investigator reads only:
AGENTS.md and any track-level AGENTS.md for tracks whose names appear in ticket titles/descriptions.The investigator brief MUST include the following two tasks:
Conflict analysis. Return {ticket_id -> affected_areas[]}. Two tickets conflict if their affected_areas[] overlap OR they share a Level 1 conflict group.
Functional-duplicate detection. For every pair of DISTINCT tickets in the set, assess whether a reasonable engineer would implement them with exactly the same change. The bar is strict: related-but-distinct work (e.g. add-login vs add-logout, two separate bug fixes in the same file) is NOT a duplicate. A duplicate pair is only flagged when the descriptions define the same functional requirement such that a single implementation resolves both. Return functional_duplicates: [{ticket_ids: [A, B], summary: "<one-sentence explanation of why the same change resolves both>"}] (empty array when none).
The investigator output contract is {ticket_id -> affected_areas[], functional_duplicates[{ticket_ids, summary}]}.
Conductor handling: store functional_duplicates[] from the investigator output into triage_result.functional_duplicates[]. Surface this in Phase 4a artifact and, on the /ds-implement-ticket integration path, in Phase 0a step 2.
HEURISTIC_ONLY stamp: when HEURISTIC_ONLY=true, Phase 2b runs Level 1 only. The artifact header is stamped: "Conflict analysis: Level 1 only (component/label overlap; >20 tickets, investigator pass skipped). Functional-duplicate detection was also skipped."
[phase: ticket-triage | phase=conflict]
Conductor-direct, pure reasoning. Implements the consume-and-remainder pipeline: each rule consumes the tickets it assigns; later rules see only the remainder. Every input ticket lands in exactly one category: deferred, in-progress-excluded, or lane-assigned.
Rule 1 - Deferral (terminal, consumes first):
Defer the following; they are removed from all downstream rules:
terminal: true (Done / Cancelled).external_dep that blocks them (the blocker is outside the set).cycle_warning: true.num_entries > lanes * 4 (documented overflow deferral; use judgment and document reason).In-progress removal (after Rule 1): tickets with in_progress: true are removed from lane assignment. They appear in the artifact badged [IN PROGRESS] and are excluded from kickoff prompts. They are NOT deferred and NOT lane-assigned.
Rule 2 - Sequential chains (consume DAG-connected components with edges):
For every connected component of the DAG that has at least one internal edge, topo-sort its members (blockers first) and assign the chain as a single lane (run as an ordered comma-list /ds-implement-ticket A, B, C batch). Non-linear components (multiple paths) are still serialized in topological order. All members of a chained component are consumed by Rule 2.
Each chain = one lane slot consumed in the cap accounting.
Rule 3 - Parallel grouping (sees only the remainder: tickets with zero internal DAG edges):
conflict-warning entry in the artifact.Rule 4 - Cap reconciliation (reorganizes lanes; never reassigns ticket categories):
Cap = --lanes N (default 3).
num_chains > cap: do NOT merge chains (they are hard dependency units). Report in the artifact: "Dependency structure requires <num_chains> sequential lanes, exceeding the cap of <cap>. Raise --lanes to <num_chains> or accept <num_chains> concurrent sessions." Proceed with num_chains lanes for chains.num_chains + num_parallel_lanes > cap: run a deterministic merge post-pass over parallel lanes only. Repeatedly merge the pair of parallel lanes that introduces the fewest new intra-lane conflicts; ties broken by (smallest combined ticket count, then lexicographically smallest member ticket_id). A merged lane runs its tickets sequentially as a comma-list batch. Each merge strictly reduces lane count, so the loop terminates. Stop when total lanes <= cap OR no parallel lanes remain to merge. If still > cap after exhausting merges, emit a cap-warning recommending a higher --lanes. Rule 3 is NOT recomputed after merges.[phase: ticket-triage | phase=distribute]
Conductor-direct. Write the artifact to docs/planning/triage-<YYYYMMDD>-<4hex>.md using the repo's absolute path. The <YYYYMMDD> is today's date; <4hex> is 4 random hex characters.
Artifact skeleton:
# Ticket Triage - <YYYYMMDD>
<!-- HEURISTIC_ONLY stamp (include only when HEURISTIC_ONLY=true):
Conflict analysis: Level 1 only (component/label overlap; >20 tickets, investigator pass skipped).
-->
## At a glance
| Lane | Tickets | Type | Notes |
|------|---------|------|-------|
| Lane 1 | A, B | chain | B blocked by A |
| Lane 2 | C, D | parallel | independent |
| ... | ... | ... | ... |
## Per-ticket summary
<!-- Est column: shows the captured estimate (story points / time estimate) or "-" when absent.
Display-only; no distribution rule consumes it.
⚠ column: populated with "⚠ large" when context_risk: high (≥5 pts); otherwise empty. -->
| Ticket | Priority | Status | Est | ⚠ | Lane | Notes |
|--------|----------|--------|-----|---|------|-------|
| A | High | To Do | 3 | | Lane 1 | |
| B | Med | To Do | 2 | | Lane 1 | blocked by A |
| C | High | To Do | 8 | ⚠ large | Lane 2 | |
| ... | | | | | | |
## Dependency notes
<!-- List external_deps and any cycle_warning entries. -->
## Conflict warnings
<!-- Only present when one or more tickets were placed by overflow (Rule 3 step 3)
or when chains exceed the cap (Rule 4). Always include the fixed caveat below
when this block is non-empty. -->
Parallel-safe grouping is heuristic - based on ticket metadata and directory-level
analysis, not file-level diffing. Verify before running lanes truly concurrently;
each /ds-implement-ticket session's own Skeptic chain still catches collisions at
merge time.
## Functional duplicate warnings
<!-- Only present when functional_duplicates[] is non-empty (Level 2 investigator ran).
List each pair and its one-sentence rationale. Omit this section entirely when
the array is empty or when HEURISTIC_ONLY=true (investigator was skipped). -->
| Pair | Why same work |
|------|---------------|
| A + B | Both implement the same email validation rule in the same form handler |
Consider deferring one ticket of each pair or merging them into a single ticket before
running /ds-implement-ticket. Running both risks a merge conflict or duplicated effort.
## Deferred tickets
| Ticket | Reason |
|--------|--------|
| X | terminal (Done) |
| Y | external blocker outside set |
## In-progress tickets
| Ticket | Assignee | Notes |
|--------|----------|-------|
| Z [IN PROGRESS] | ... | Excluded from kickoff prompts |
## Kickoff prompts
<!-- One block per lane. Use absolute paths where paths are involved.
In-progress and deferred tickets are NOT included here. -->
**Lane 1** (sequential chain - run as one session):
/ds-implement-ticket A, B
**Lane 2** (parallel - can run concurrently with other lanes):
/ds-implement-ticket C, D
[phase: ticket-triage | phase=draft]
Skip condition: if the artifact contains zero lanes AND zero chains (e.g. all tickets are deferred or in-progress), skip Phase 4b entirely and proceed to output.
Otherwise: spawn a fresh background Skeptic on the artifact with this adversarial brief:
"Review this triage artifact. Check: (1) Dependency ordering - are blockers placed before the tickets they block within each chain? (2) Parallel safety - are tickets in the same lane genuinely non-conflicting per the Phase 2b analysis? (3) Deferral justification - is each deferred ticket's reason accurate and not overcautious? (4) Kickoff prompt completeness - does every non-deferred, non-in-progress ticket appear in exactly one lane's kickoff prompt? (5) Cap reconciliation - if Rule 4 fired, was the merge post-pass applied correctly and documented?"
Max 3 fix passes, then escalate to the operator with open findings listed.
[phase: ticket-triage | phase=skeptic-review]
After Phase 4b sign-off (or after the skip condition triggers), print to chat:
HEURISTIC_ONLY=true, restate the Level 1 stamp.[phase: ticket-triage | phase=complete]
Non-goals (this command intentionally does NOT):
/ds-implement-ticket or spawn any implementation agent..agentic/batch-state.json, .agentic/loop-state.json, .agentic/tasks.jsonl, or any other .agentic/ state file.Distinction from related commands:
/ds-implement-ticket - executes a ticket through to a merged PR; /ds-ticket-triage is upstream planning only.orchestration-planner - decomposes a single architect plan into ordered units; /ds-ticket-triage operates on a tracker-sourced ticket list before any architect runs.Yolo-guard: the kickoff prompts in the artifact are conductor inputs, not execution bypasses. Pasting a kickoff prompt into a session still invokes the full /ds-implement-ticket flow: risk classification, architect, Skeptic, engineer, QA gate. See content/references/trigger-catalog.md §d.
| Condition | Behavior |
|---|---|
| No args, no tracker | Print "No tracker configured - an explicit ticket list or URL is required when no tracker is connected." and exit. |
| No args, 0 assigned | Print "No open tickets assigned to you." and exit. |
| No args, 1 assigned | Print "Single ticket: run /ds-implement-ticket directly." and exit. |
| No args, >=2 assigned | Print resolved ticket IDs, then proceed into Phase 1+ as for an explicit list. |
| Single ticket | Print "run /ds-implement-ticket directly." and exit before Phase 1. |
| All tickets independent (no DAG edges) | Rule 2 is a no-op; all tickets go to Rule 3 parallel grouping. |
| Circular dependency | Break at lowest-confidence link; defer both with cycle_warning. Do not abort. |
| Multi-prefix input (Jira + Linear IDs) | Phase 0 normalizes as usual; Phase 1 routes each ID to the correct MCP tool. Conflict analysis treats all tickets uniformly. |
| JQL returns many results | Phase 0's 50-result cap applies first (truncate + warning). Then, on the surviving set: if count >20, the HEURISTIC_ONLY gate fires (Level 1 conflict analysis only; header stamped). Both rules sequence in that order; a 60-result JQL trips both. |
| Terminal-status ticket (Done/Cancelled) | Deferred via Rule 1 with reason "terminal". Not included in lane assignment or kickoff prompts. |
| In-progress ticket | Carried through analysis; removed from lane assignment after Rule 1. Shown badged [IN PROGRESS]. Excluded from kickoff prompts. |
| No tracker configured (with explicit input) | Skip Phase 1; run Phase 2a with zero link data; run Phase 2b Level 1 with zero component/label data; print notice. |
Every tracker and MCP call soft-fails: log and continue. A fetch failure on one ticket never aborts the triage of the remaining set. Fetch-failed tickets are treated as independent with no known metadata. The command never errors out on external API failure.
Emit one breadcrumb per phase as shown in each section above. The terminal breadcrumb is [phase: ticket-triage | phase=complete].