sentry-triage
Run Fern CLI Sentry false-positive triage for buildwithfern/cli. Use when investigating Sentry CLI issues, classifying false positives, updating the triage ledger, or creating PRs for Sentry error fixes.
适合你,如果经常处理 Sentry 错误报告并需要区分真伪
npx oh-my-skill add fern-api/fern/sentry-triagecurl -fsSL https://oh-my-skill.com/install.sh | bash -s -- fern-api/fern/sentry-triagenpx oh-my-skill verify fern-api/fern/sentry-triage怎么用
商店整理自技能原文 · 版本 aeafcf1 · 表述以原文为准这项技能让 Claude 获取 buildwithfern/cli 项目的 Sentry 未解决问题,根据台账过滤、去重现有 PR,按调用栈分组后并行启动子 agent 进行分类和修复决策,最终汇总并可选地创建父协调 PR。
当你要求调查 Sentry CLI 问题、分类误报、更新分类台账,或为 Sentry 错误创建 PR 时,技能会被触发。
技能原文 SKILL.md
Sentry CLI False-Positive Triage
Scope
- Sentry org:
buildwithfern - Sentry project:
cli - Use the repo-baked Sentry CLI:
pnpm exec sentry-cli. - Default query: unresolved only, unless the task explicitly says to re-check resolved issues.
Required Files
Read these before proposing code changes:
.devin/automation/sentry-triage/DESIGN_CHOICES.md— general principles, not pre-written solutions..devin/automation/sentry-triage/ledger/— one JSON file pershortId(e.g.ledger/CLI-2W.json); plusledger/_meta.jsonfor repo-wide constants. Read only the rows you need..devin/automation/sentry-triage/SUBAGENT_CONTRACT.md— passed to every spawned subagent.
The ledger is one file per shortId. Parallel subagent branches touch disjoint files, so merge conflicts are eliminated by construction. Do not load or rewrite the whole directory unless a task explicitly requires broad record maintenance.
Workflow Overview
- Parent — fetch Sentry, ledger-filter (cheap lookup), existing-PR dedupe (script), group by call site (hypothesis from Sentry stacks), write Group Plans, spawn.
- Spawn — strict 1:1: one parallel subagent per eligible group. N groups → N parallel subagents, never one subagent told to handle several groups and never sequential. See [Subagent Orchestration](#subagent-orchestration).
- Reconcile — collect subagent results, sanity-check ledger, summarize, optionally open one parent reconciliation PR. See [Parent Reconciliation](#parent-reconciliation).
Classification authority lives in the subagent, not the parent. The parent does cheap, structural decisions (ledger filter, dedupe, grouping hypothesis). The subagent has the code in front of it and owns the actual disposition call — including keep_sentry, ignored, pending_review, and "the parent's grouping was wrong." The parent's Group Plan is a working hypothesis, not a binding classification.
Fetch
pnpm exec sentry-cli issues list \ --org buildwithfern \ --project cli \ --status unresolved pnpm exec sentry-cli issues list \ --org buildwithfern \ --project cli \ --id <ISSUE_ID>
If the baked CLI cannot show enough detail for a shortId, use the Sentry API through pnpm exec sentry-cli or an authenticated project-approved Sentry command. Keep payloads small.
Ledger Filter
- Collect current
shortIds from Sentry. - Query only those rows:
for id in CLI-2W CLI-2V; do
path=".devin/automation/sentry-triage/ledger/$id.json"
if [[ -f "$path" ]]; then
jq --arg shortId "$id" '{shortId: $shortId, disposition, duplicateOf, problemSignature, prOrIssue}' "$path"
else
jq -n --arg shortId "$id" '{shortId: $shortId, status: "unknown"}'
fi
done
- Skip exact
shortIdfiles with terminal disposition:shipped,ignored,duplicate, orkeep_sentry. - Re-process
pending_review. - Similar
problemSignaturetext is only a hint. Never treat a similar past issue as proof the currentshortIdis fixed. - Listing all rows:
ls .devin/automation/sentry-triage/ledger/CLI-*.json._meta.jsonholds repo-wide constants and rarely changes.
Existing-PR Dedupe Procedure
After the ledger filter, run the dedupe script for every remaining shortId. Do not run ad-hoc gh searches for this purpose.
gh auth status .devin/automation/sentry-triage/scripts/find-existing-pr.sh CLI-44 CLI-4T
Steps the script performs, per shortId:
- Ledger lookup —
prOrIssueanddispositionfromledger/<SHORT_ID>.json; ifprOrIssueis a PR URL, fetch PR state (any branch). - Triage-branch search — one
gh pr listcall per run for open PRs with head branch prefixfix/cli-sentry-triage/; pershortId, match when the branch name, title, or body contains the id (case-insensitive). - Verification metadata — for each candidate, fetches
files,title,body,state,headRefName.
PR discovery does not search all open PRs in the repo — only triage-shaped branches (plus ledger URLs).
Stdout is a JSON array (one object per shortId with ledger and candidates). For each shortId, judge against the boundary you identified:
none— no candidate covers the boundary; eligible for a subagent.covered— a candidate PR's diff/title/body matches the group's boundary and fix; record theprOrIssueupdate for the parent reconciliation PR (do not spawn).partial— someshortIds covered, others not; split the group and only spawn for uncoveredshortIds.
If the script exits non-zero (auth failure, rate limit, network), halt the run and ask a human to fix gh auth or rate before proceeding. The --limit 100 triage-branch cap is unlikely to be hit; if exceeded, narrow the filter and re-run.
Env vars: FERN_REPO (default fern-api/fern), LEDGER_DIR (default .devin/automation/sentry-triage/ledger).
Grouping Rule
Group by call site, not by title alone.
- A call-site group is a set of Sentry issues that fail from the same function, boundary, or throw/catch path and can be fixed by the same code change.
- Grouping should be rare. Most Sentry issues are unique and should become their own investigation and PR.
- Multiple
shortIds may share one PR only when the stack proves the same function or boundary produces the same false-positive classification. - Do not group issues just because the messages look similar, the same dependency appears, or a prior ledger row has a similar
problemSignature. - The parent finalizes the group list before spawning. Mid-stream regrouping is not allowed. If a subagent disproves a group, it stops and returns findings; the parent re-plans on the next run.
Parent investigation scope. Parent reads Sentry stacks and may optionally grep the codebase for the top frame. Do not open source files — the subagent does the source-code reading. The Group Plan is built from Sentry data and ledger context, nothing deeper.
Before spawning, write one Group Plan block per group. The plan is the parent's working hypothesis; the subagent verifies it against code and may return any disposition.
Group: <call site or function — hypothesis from top stack frame> ShortIds: <CLI-XX, CLI-YY> Evidence: - top frames (>=3, with file:line where available) - exception type and message - breadcrumb tail if relevant - event count and lastSeen ExistingPR: <none | PR URL and why it covers/does not cover this group> Branch: fix/cli-sentry-triage/<YYYY-MM-DD>-<up-to-3-short-ids-kebab>
Evidence is the subagent's only window into Sentry — the subagent is forbidden from refetching, so include everything it needs to locate and verify the boundary. Paste the data as text; no need for structured JSON.
The parent does not propose a fix or pre-match DESIGN_CHOICES.md principles — the subagent owns both once it reads the code. The parent contributes only what it can reliably produce from Sentry data: the call-site hypothesis, the ShortIds set, the raw evidence, the dedupe result, and the branch name. The subagent surfaces any new principle worth recording via newPrincipleProposal.
Any group with no ExistingPR coverage and no terminal ledger row is eligible for a subagent. The parent must not pre-classify groups as keep_sentry, ignored, or pending_review to avoid spawning; those decisions belong to the subagent. The only parent-side shortcuts are:
- Skip when the ledger row is already terminal (
shipped,duplicate,keep_sentry,ignored). - Skip when the dedupe script confirms an existing PR fully covers the group (record
prOrIssuefor the parent reconciliation PR).
Anything else gets a subagent.
Subagent Orchestration
One subagent per eligible group. Strict 1:1, no exceptions.
For every eligible group from [Grouping Rule](#grouping-rule), the parent spawns exactly one subagent. The mapping is:
| 1 Group Plan | 1 subagent | 1 branch | 1 PR | 1 disjoint set of ShortIds |
- N eligible groups → N parallel subagents in the same spawn batch. Never one subagent handed multiple Group Plans; never sequential spawning to "see how the first one goes".
- Spawn via the host's parallel-worker primitive:
- Devin: managed Devins (one separate session per group).
- Cursor:
Tasktool withrun_in_background: true, called once per group within a single message. - Other hosts: the equivalent parallel-worker mechanism.
- Subagent rules live in [
SUBAGENT_CONTRACT.md](SUBAGENT_CONTRACT.md). Pass only that file's path plus one Group Plan block. Never paste multiple Group Plans into one spawn prompt. - Each subagent works on its own fresh branch off
main. Branches must not be stacked across groups. - Each subagent owns: its branch, its fix, its PR, and ledger files for its
ShortIdsonly.
Anti-patterns (do not do these):
- Spawning one subagent with a list of Group Plans ("here are 5 groups, work through them").
- Spawning subagents sequentially across groups, even when the parent feels uncertain about parallelism.
- Letting one subagent open a second PR because it noticed another group while reading code (that's a re-plan, not a scope expansion — see [Stop and return findings](SUBAGENT_CONTRACT.md#stop-and-return-findings-no-pr-if)).
- Bundling several
ShortIdsfrom different call sites into one "miscellaneous" group to spawn fewer subagents.
If the parent is uncertain a group is well-formed, leave it unspawned and roll it into the next run — skipping is better than merging groups.
Parent spawn prompt (uniform for every group, one spawn per group):
Read .devin/automation/sentry-triage/SUBAGENT_CONTRACT.md and follow it. Group Plan: <paste the single Group Plan block here>
Parallel-Safety Rules
- Branch names per group are unique by the date +
shortIdscheme (eachshortIdbelongs to exactly one group). - Ledger writes are partitioned by
shortIdacross separate files (ledger/<SHORT_ID>.json); parallel subagents never touch the same file. This is the primary reason for the per-file layout. DESIGN_CHOICES.mdis parent-only. Subagents returnnewPrincipleProposalinstead of editing it.ledger/_meta.jsonis parent-only and rarely edited.- If two groups share a code path mid-investigation, both subagents stop and return findings; the parent re-plans.
Parent Reconciliation
After all subagents finish:
- Collect each subagent's
prUrl(orskipped: <reason>),shortIdsTouched,principlesApplied,newPrincipleProposal. - Ledger collision check (per-file layout makes this trivial): no two open triage PRs should include the same
ledger/CLI-XX.jsonfile. Verify withgh pr view <num> --json filesagainst each open triage PR. - Print a per-group summary: group label,
ShortIds, PR URL or skip reason. - Optional parent reconciliation PR (only when there is something to write):
- Ledger
prOrIssueupdates for groups the parent markedcoveredduring dedupe. - 1–3 new
DESIGN_CHOICES.mdbullets surfaced vianewPrincipleProposal, after human review.
The reconciliation PR contains no code changes, only ledger pointer updates and/or DESIGN_CHOICES.md edits. Branch: chore/cli-sentry-triage/<YYYY-MM-DD>-reconcile.
PR Rules
- One PR per call-site solution group, opened by the subagent (see [Subagent Orchestration](#subagent-orchestration)).
- A run may create multiple PRs; do not create one catch-all triage PR.
- Before creating a branch or PR, the [Existing-PR Dedupe Procedure](#existing-pr-dedupe-procedure) must have run; if an open triage PR already addresses the group, do not spawn a duplicate subagent.
- If a re-run finds the same
ShortIdsstill unresolved and an open triage PR already exists at the right boundary, push additional commits to that branch rather than creating a new PR (host-agent convention). Most cases never reach here because terminal ledger rows are skipped at the ledger-filter step. - Branch:
fix/cli-sentry-triage/{date}-<short-ids>(e.g.fix/cli-sentry-triage/2026-11-03-cli-44-cli-4t-cli-4v). - Use ISO date (
YYYY-MM-DD) and at most threeshortIds in the branch name, lowercased and kebab-cased. - PR title must include the solved
shortIds. If more than three, list the first three and summarize the family. - PR description lists every solved
shortIdand a short fix note. - Update only the per-
shortIdfiles under.devin/automation/sentry-triage/ledger/for that group, in the same PR as the code. Never touch other rows' files or_meta.json. - Add
packages/cli/cli/changes/unreleased/when CLI behavior or reporting changes.
Ledger Records
One file per issue at .devin/automation/sentry-triage/ledger/<SHORT_ID>.json. Required fields:
titleproblemSignaturedispositionrationalefixSummaryprOrIssuelastAnalyzedduplicateOfwhendispositionisduplicate
The shortId is the filename (no shortId field inside the file). ledger/_meta.json holds repo-wide constants (schemaVersion, project) and is rarely edited.
Disposition values: shipped, duplicate, keep_sentry, ignored, pending_review. pending_review is the only non-terminal value (re-processed next run); the rest are terminal. Full decision rules live in [SUBAGENT_CONTRACT.md](SUBAGENT_CONTRACT.md) (Choosing a disposition).
Sentry Resolution
Do not mark Sentry issues resolved unless the exact shipped CLI release is known and explicitly provided. Prefer explicit release resolution over "next release".