--- name: triage-frontend-ticket description: 'Use when given a Linear ticket (URL or ID) for lago-front and the technical groundwork is missing — a defect report whose validity is unknown, or a change request nobody has costed against the code. Typically a Front-end ticket in Triage/Backlog/Scoping. Triggers on "/triage-frontend-ticket ", "triage this ticket", "fai analisi tecnica di questo ticket", "is this actually a bug?", "is this feasible?".' --- # Triage frontend ticket **Input:** one Linear ticket URL or identifier (e.g. ``). If none was given, ask with AskUserQuestion and stop until given. **Repo:** the lago-front checkout (`front/` in the lago monorepo). If the session is not in lago-front, STOP — this skill reasons about this codebase only. **Output:** one comment posted on the ticket, and — only for a ticket sitting in `Triage` that the analysis actually resolved — a move to `Backlog`. Nothing else on Linear is touched. **Who reads that comment:** whoever picks the ticket up next — a human deciding whether to schedule it, a developer opening the editor, or an agent implementing it. Assume none of them will redo the analysis. So the comment is a **handoff document**: everything needed to start work is in it, in a form that reads as well to a person as it parses to an agent. That is what step 6's **Implementation handoff** block is for. This skill is deliberately pipeline-agnostic. It ends at the posted comment and makes no assumption about how the work gets done afterwards — by hand, by an agent, or by an automated pipeline. If your team uses one that reads ticket comments (`/loop-run` does, through `loop-spec`), the handoff block is already in the shape it needs; if not, it is simply a well-specified ticket. **Read `LEARNINGS.md`** (alongside this file) before you judge anything. It holds rules learned from real outcomes and overrides the defaults here where they conflict — within the limits stated in that file: a learning may tune judgement, never soften a guardrail. Create a todo per numbered step below before starting. ## 1. Fetch, gate, classify Extract the issue id (`[A-Z]+-\d+`), then reset the review budget so a re-triage starts clean: ```bash front/scripts/iter-budget.sh reset triage-review front/scripts/analysis-depth.sh reset ``` Fetch via Linear MCP `get_issue` (with `includeRelations`) **and** `list_comments` — repro steps, scope changes and decisions often live only in comments, and a Slack attachment subtitle often holds the original report. **Then enumerate the attachments and say what you could and could not read.** A Loom or a screenshot is frequently the only place the actual gesture exists. You cannot watch a video: state that, ask the operator to describe what happens in it, and never replace it with a plausible reconstruction — a repro you invented is how an analysis ends up explaining a defect nobody reported. Check every gate in order. Exactly one of them posts anything; the rest stop silently. Do not improvise a third outcome. - **Not analyzable** → post the *Needs info* comment (step 6) **with the footer** (step 8), then stop: no independent review (there is no finding to re-derive) and no status move (the ticket is still waiting on the reporter). - **Every other failure** → STOP, report to the operator, post nothing. | Gate | Check | On failure | | --- | --- | --- | | **Already triaged** | Any comment body contains ` ``` **Two fingerprints, because a ticket changes in two places.** Step 1 fetches the comments precisely because scope changes, repro details and decisions land there and never make it back into the description — so a description-only key reports "nothing new" on a ticket whose comments have since redefined the work. ```bash # what the ticket says printf '%s' "$DESCRIPTION" | shasum -a 256 | cut -c1-12 # which comments exist, in order — ids only, so editing prose in a comment is not a re-triage # trigger while a NEW comment is. Exclude comments carrying this skill's footer, otherwise # posting immediately invalidates the fingerprint it just wrote. printf '%s' "$COMMENT_IDS" | shasum -a 256 | cut -c1-12 ``` With no qualifying comments, use `cmt-sha=none`. Then report to the operator in chat: type, verdict, one-line reason, review outcome, comment URL, and whether the status moved (step 9). Short and plain — the analysis already lives on the ticket. ## 9. Promote out of Triage — only when earned A ticket in `Triage` is waiting for someone to establish whether there is work here. A resolved analysis answers that, so the ticket can move on to `Backlog` — where the team prioritises it. Anything further (`Ready for dev`, an assignee, a cycle) is a scheduling decision this skill does not make. **Re-fetch the ticket immediately before moving it.** The analysis takes minutes, and a human may have triaged it in the meantime; acting on the status captured at step 1 would overwrite their decision. If the re-fetch no longer says `Triage`, leave it alone and report that somebody moved it first. Move it **only** when every one of these holds: - the status **at re-fetch time** is exactly `Triage` — a ticket already in `Backlog`, `Scoping` or beyond is left alone - the verdict is **confirmed bug**, **feasible as asked**, or **feasible with caveats** - the independent review returned `PASS` - the comment posted successfully ``` save_issue: { id: , status: "Backlog" } ``` Leave the ticket in `Triage` for every other outcome, and say why in the report: | Outcome | Why it stays in Triage | | --- | --- | | **not a bug** | Someone has to decide whether to close it, and that is not a technical call | | **cannot determine** / **blocked** | Still waiting on the missing facts the comment asked for | | review exhausted its budget without `PASS` | The analysis is unconfirmed; promoting it would launder that | A failed status update is a warning, never a failure of the run: the comment is the deliverable and it is already posted. Report that the move did not go through and move on. ## Hard rules - **On Linear, only the comment and the one `Triage` → `Backlog` move.** No assignee, no labels, no cycle, no closing, and never a status change from anywhere other than `Triage`. **Why the label ban is not arbitrary:** an `ai-augmented` or `claude-*` label, and the `Scoping` state, are entry gates for the org's existing automated pipeline — it skips any ticket carrying them. Applying one here would make the ticket permanently invisible to that pipeline, silently. `Backlog` is safe because it is a pre-dev state that pipeline accepts. Do not add a convenience label to mark analysed tickets; the footer already does that. - **No code edits.** This skill analyses; implementing is a separate task — by hand or through whatever pipeline the team uses. - **Never post twice on the same ticket state.** The footer gate is the mechanism; respect it. - **Print every `file:line` you cite before posting.** An unverified citation is reference rot waiting to happen. - **A matching symptom is where to look, never what to conclude.** The regression table in step 2a produces hypotheses; only the call site produces findings. - **A real defect is not automatically the reported defect.** Every cause carries its precondition and whether the reporter's steps meet it (step 3b). Unmet → the reported symptom is still unexplained, and saying so is the deliverable. - **For interaction, layout and rendering symptoms, reproduce in the running app.** jsdom has no layout, no scroll and no paint; a green harness there is not evidence about what the reporter saw. - **Scope fences come after reproduction, never before.** Declaring a file correct up front is how the actual cause survives triage, implementation and QA untouched. - **Never dress a guess as a finding.** No evidence → *cannot determine* or *blocked*, not a confident story. - **Someone will edit code straight from the handoff block.** Exact paths, one approach, assertions not intentions. A vague handoff produces a wrong implementation, which is worse than no analysis. - **Never accept the ticket's description of current behavior.** Verify it in the code — for change requests this is the most common error in the report. - **The project's documented patterns outrank both the neighbouring code and your own instinct.** A fix that works but violates `CLAUDE.md` is a finding to reject, not to propose. - **The review budget lives on disk, not in your memory.** Every review charges `iter-budget.sh`; a non-zero exit is final. - Comment in English regardless of the language the operator is using.