From superpowers-plus
Enforces comment-volume discipline on Linear tickets by classifying proposed comments as NEW, EDIT, or CONSOLIDATE before allowing commentCreate. Prevents thread explosion and routes progress updates to edit existing comments.
How this skill is triggered — by the user, by Claude, or both
Slash command
/superpowers-plus:linear-comment-gateThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
> **Purpose:** Stop Linear comment-thread explosion. Classify every proposed comment as NEW, EDIT, or CONSOLIDATE before any `commentCreate` call.
Purpose: Stop Linear comment-thread explosion. Classify every proposed comment as NEW, EDIT, or CONSOLIDATE before any
commentCreatecall. Incident: incident-2026-1507 (2026-06-12) -- 10 individual engineering status comments on one ticket over 12 hours, all about MR !23. Required a manual consolidation session to make the ticket readable. Core rule: One living comment per ongoing work thread. Progress updates amend the existing comment. New comments are for state transitions and new work items only. Scope note: This gate lives inskills/issue-tracking/and is required by both engineering and PM debunker skills. The one-living-comment rule applies equally to both.
Two paths bypass Steps 2-3 (classification is skipped) but still run Step 4 to emit a traceable preflight block:
action=EXEMPT (reason=threaded-reply). Debunker applies action=NEW implicitly.**Correction to [date] comment:**: skip to Step 4 with action=EXEMPT (reason=factual-correction). Debunker applies action=NEW."First comment by this author on this ticket" is NOT an exemption — Step 3 handles it correctly (0 same-signature comments →
NEW). Run the full gate.
Fetch all comments on the target issue before doing anything else. Record:
If you cannot fetch comments: STOP. Do not post until you can.
Extract the primary work artifact from both the proposed comment and each existing same-author comment.
| Artifact pattern in comment text | Signature key |
|---|---|
MR reference !NN | MR !NN |
Branch name fix/TICKET-XXXX-* or feat/TICKET-XXXX-* | branch:TICKET-XXXX |
| Commit SHA (7+ hex chars) | associate with its MR signature if determinable |
Named env var or feature flag (e.g. GREETING_PROTECTION_MS) | feature:<NAME> |
| "reverted" / "rolled back" / "revert SHA" | state:revert |
| "work ceased" / "closed" / "cancelled" / "shipped to production" | state:terminal |
| "deployed" / "merged to main" | state:deploy |
| No extractable artifact | general-update |
general-updaterule:general-updatesignatures always produceaction: NEWregardless of existinggeneral-updatecomment count. Topic overlap cannot be reliably determined for unstructured updates — do not merge.
State signatures (state:*) always produce action: NEW regardless of existing comment count -- terminal events warrant their own comment.
| Same-signature same-author comments | Existing thread | Proposed content type | Action |
|---|---|---|---|
| 0 | — | anything | NEW |
| 1+ | has state:terminal or state:deploy | any | NEW (thread closed; start fresh) |
| 1 | open | state transition | NEW |
| 1 | open | progress update | EDIT |
| 2+ | open | state transition | NEW |
| 2+ | open | progress update | CONSOLIDATE |
Progress update = pipeline status, test count change, MR state change, review finding addressed, code pushed, approval pending, timer values, build numbers. When in doubt, classify as progress update.
State transition = ship to production, revert/rollback, work ceased, ticket closed/cancelled, new external blocker.
PREFLIGHT: LINEAR-COMMENT-GATE
- target_issue: TEAM-NNNN
- total_comments: N
- same_author_comments: N (ids: [...])
- proposed_topic_sig: [extracted signature]
- overlapping_existing: [comment IDs with same signature] | NONE
- proposed_content_type: progress-update | state-transition
- action: NEW | EDIT | CONSOLIDATE | EXEMPT (reason=...)
- consolidation_complete: YES | NO | N/A # N/A for first-run action=NEW or EDIT (no consolidation needed)
- GATE: PASS | FAIL (reason)
Rules:
action=EXEMPT (reason=...): GATE = PASS. Proceed directly to debunker. Debunker applies action=NEW for factual-correction; skips classification check for threaded-reply.action=NEW: GATE = PASS immediately. Proceed to debunker.action=EDIT: GATE = PASS. Proceed to debunker which validates content; then call commentUpdate per EDIT Procedure.action=CONSOLIDATE AND consolidation_complete=NO: GATE = FAIL. Run Consolidation Procedure, then re-emit this block with consolidation_complete=YES.action=CONSOLIDATE AND consolidation_complete=YES AND re-run action is EDIT: GATE = PASS. Proceed to debunker; debunker appends proposed new content via commentUpdate.action=CONSOLIDATE AND consolidation_complete=YES AND re-run action is again CONSOLIDATE: GATE = FAIL (consolidation-loop). Stop; surface surviving same-signature comment IDs for manual review.When action=EDIT, do NOT call commentCreate. Instead:
**YYYY-MM-DD HH:MM -- [brief label]:** [new content]
linear-comment-debunker-engineer for engineer comments, linear-comment-debunker-pm for PM comments) against the drafted section ONLY — GATE must PASS before continuingcommentUpdate with the full updated body (existing body + appended section)An ongoing work thread ends when the ticket reaches a terminal state (Done, Cancelled, Merged) or the work artifact (MR, branch) is closed. Until then, the same-topic comment is "living."
Run this before resuming the comment posting workflow:
Resolve current author identity (REQUIRED before any delete):
viewer { id name } (Linear GraphQL me query) to get currentAuthorIdDraft one consolidated comment (historical content only — do NOT include proposed new content):
Consolidated [topic] history -- replaces prior comments**YYYY-MM-DD HH:MM -- [brief label]:** [content]Post the consolidated comment via commentCreate
Delete each original same-topic same-author comment via commentDelete:
comment.user.id == currentAuthorId (resolved in Step 0)GATE: FAIL (reason=consolidation-incomplete, undeleted_ids=[...]), notify the user for manual cleanup. Do NOT proceed to Step 4.Re-run Steps 1-4 from scratch (re-fetch all comments, re-classify) with consolidation_complete=YES:
action=EDIT (the consolidated comment is the single surviving same-topic entry)commentUpdateCONSOLIDATE: STOP. Set GATE: FAIL (reason=consolidation-loop). Surface surviving comment IDs for manual review. Do not attempt another cycle.| Failure | Recovery |
|---|---|
| Classifying MR status as state-transition to avoid consolidation | Re-read the table -- "pipeline green", "tests passing", "approval pending" are progress updates |
| Skipping gate for "quick" updates ("this one is obviously fine") | No exemptions for speed -- self-exemption is exactly how incident-2026-1507 happened |
| Consolidation drafted but not posted before proceeding | GATE stays FAIL; complete the procedure before re-entering debunker |
commentDelete fails for one or more originals | Record undeleted IDs; set GATE FAIL; notify user for manual cleanup; do NOT re-attempt commentCreate |
Re-run after consolidation produces CONSOLIDATE again | STOP: consolidation-loop detected. Surface surviving same-signature comment IDs for manual review |
| Deleting another author's comment | Step 0 must resolve currentAuthorId via viewer query; only delete where comment.user.id matches |
linear-issue-verify -- REQUIRED before this gate runslinear-comment-debunker-engineer -- runs AFTER this gate clears (PASS) for engineer commentslinear-comment-debunker-pm -- runs AFTER this gate clears (PASS) for PM-framed commentsexhaustive-audit-validation -- use for retroactive cleanup on tickets with 5+ same-author comment pileupsnpx claudepluginhub bordenet/superpowers-plus --plugin superpowers-plusGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.