一键导入
flaky-test-fixer
Fix flaky Ruby RSpec tests in Canvas LMS. Classifies failure patterns, applies documented fixes from the KB, and drives the full batch workflow.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Fix flaky Ruby RSpec tests in Canvas LMS. Classifies failure patterns, applies documented fixes from the KB, and drives the full batch workflow.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
| name | flaky-test-fixer |
| description | Fix flaky Ruby RSpec tests in Canvas LMS. Classifies failure patterns, applies documented fixes from the KB, and drives the full batch workflow. |
| user-invocable | true |
| allowed-tools | ["Read","Grep","Glob","Bash","Edit","Write","Agent","AskUserQuestion","mcp__atlassian__getJiraIssue","mcp__atlassian__editJiraIssue"] |
Fix flaky Ruby RSpec tests in Canvas LMS by classifying failure patterns against a knowledge base (KB) of documented cases, applying the appropriate fix, and driving the full batch workflow — from test selection through CI verification and KB update. The skill orchestrates the human-in-the-loop cycle: gathering failure data, implementing fixes, pushing for CI verification, and capturing learnings for future sessions.
kb/process.md and kb/style.md — they define the workflow
and conventions for every fix batch.kb/case_*.md) are read
on-demand during classification — do not load them all upfront.Drive the session through these phases. The user may provide multiple tests at once, group related tests, skip steps they've already done, or offer observations at any point — adapt naturally. Examples:
Use AskUserQuestion: "Provide the CSV data values (no header needed) and failure report MHTMLs for the next test (or group of related tests)."
The user pastes only the data values — match them positionally to the
column definitions in kb/process.md § "Gather failure data" table.
If the user has already provided them in the same message that invoked the skill, skip the prompt and proceed.
For each test (or group):
Read the failure report(s) — extract error type, failing line, backtrace, Rails log entries, and screenshot observations.
Read the full spec file — not just the failing line. Check
before blocks, shared contexts, and helper methods.
If the test already carries a # flaky-fix: tag:
getJiraIssue and scan the
Description for a matching (flaky-fix) section per S-16.
This gives the prior root cause, what was tried, and the fallback
plan — feed this into classification before reading the new failure.AskUserQuestion to request the detailed breakdown CSV from
the Observe worksheet. This is mandatory for S-16 — the aggregate
stats (flaky_fails total) are useless after a prior fix has been
applied; only the daily timeline reveals whether the prior fix
helped. Important: the breakdown CSV contains only flaky
failure events (runs where the test failed at least once), not all
test executions. It is only useful for computing average daily
flaky failures — not pass rates, total runs, or reliability
percentages. Build a daily flaky-failure count and compare the
rate before vs after each prior fix merge date to classify the
outcome (A/B/C).Classify using the table below. Read the referenced case file.
Present the root-cause analysis to the user before implementing.
Implement the fix locally following the case's procedure. Tag the
test with # flaky-fix: <JIRA> per S-01 (in kb/style.md).
Apply the changes to the working tree — do not stage or commit yet.
Verify every change addresses the root cause. For each change in the diff, ask: does this directly fix the identified failure mechanism? Drop any change that does not — cosmetic refactors, marginal optimisations on an unrelated axis, and "while we're here" cleanups dilute the patch without reducing flakiness.
Re-evaluate custom_timeout per S-09 (in kb/style.md) if the
fix changes the test's runtime or the file will be in HEAD.
Check for sibling tests with the same pattern — fix proactively.
Tag every satellite with # flaky-fix: <JIRA> per S-01, including
tests whose fix lives entirely in the shared example or before
block. Verify all tags before proceeding to step 9.
Show the diff and use AskUserQuestion to explicitly ask the
user to approve or reject before proceeding. This is a mandatory
human-in-the-loop gate — call AskUserQuestion even in Auto mode.
Do not proceed to step 10 until the user answers affirmatively.
Once the user approves via AskUserQuestion:
a. Commit and push:
git add the changed files, git commit --amend --no-edit
(same Change-Id per S-05), push to Gerrit.
b. Capture the PS number from the push output. Gerrit prints
the change URL in the push response:
remote: https://gerrit.instructure.com/c/canvas-lms/+/NNNNN
Extract NNNNN — this is the PS number for the "Fix applied" field.
c. Post to Jira using the MCP workflow from S-02. Compose the
(flaky-fix) section from the data already in session context:
| Field | Source |
|---|---|
it description | read from the spec file in step 2 |
| Spec path | from the CSV row / failure report |
| Stats | from the CSV row provided in Phase 1 |
| Satellite-fixes | from step 8 (sibling tests fixed) |
| Error | from the failure report (MHTML error line) |
| Prior fixes (S-16) | from step 2 (if # flaky-fix: tag existed) |
| Root cause | from the analysis in steps 3–4 |
| Fix applied (PS NNNNN) | from the analysis + PS number from step b |
| If insufficient | from the analysis |
Then follow the S-02 workflow: getJiraIssue → scan for existing
section → append or replace → editJiraIssue.
d. If the MCP call fails (tools unavailable or auth error): follow the first-time setup instructions in S-02, then retry. Do not fall back to HTML files.
Each test fix is pushed to the PS before moving to the next test. After pushing and posting to Jira, ask: "Ready for the next test?"
The user decides when to end the batch. The 5–6 unique-case guideline
in kb/process.md is a soft starting point, not a hard cap. When
counting cases for the summary, count only unique primary cases —
satellites (same shared example in a different context, sibling tests
with the same pattern) and skipped/deferred tests do not count.
After all tests are fixed, execute steps 5a–5d in kb/process.md:
verify CI (2 consecutive clean runs), update KB cases, verify the
lookup tables in README.md and SKILL.md, amend the commit message
to cover all fixes, push the final PS, and summarise the batch (tests
fixed, patterns used, KB changes, tests skipped and why).
Match the failure report against these signatures. Read the referenced case file for the full diagnostic procedure and fix pattern.
| Error / Signal | Pattern | Read |
|---|---|---|
SpecTimeLimit::Error, custom_timeout too low | Timeout budget | kb/case_02.md |
SpecTimeLimit::Error at 60s absolute cap | Cap optimisation | kb/case_03.md |
ScriptTimeoutError during get / page load | Chrome async script timeout | kb/case_02.md (with_timeouts) |
RuntimeError from JS console (CDP / session) | Browser artifact | kb/case_04.md Pattern A |
NoSuchElementError after page load / refresh | Deferred AJAX miss | kb/case_04.md Pattern B |
ExpectationNotMetError, wrong value from DB | DB ordering assumption | kb/case_04.md Pattern C |
ExpectationNotMetError after navigate-away | AJAX pref save race | kb/case_04.md Pattern D |
| All tests fail together, all retries, varies by worker | Process state contamination | kb/case_12.md |
NoSuchElementError on AJAX list, no Processing by | JS bundle init race | kb/case_06.md Pattern A |
AJAX list empty despite DB data, loaded: true | Browser HTTP cache | kb/case_06.md Pattern B |
Error in prepend_before/after, wrong screenshot | Browser state leak | kb/case_07.md |
| Data contract violation in pipeline output | Pipeline substitution | kb/case_01.md |
InstUI portal never mounts (findByRole timeout) | rAF starvation | kb/case_09.md |
Mixed fireEvent/userEvent on CanvasAsyncSelect | Focus/blur race | kb/case_10.md |
Unguarded ref + isLoading in observer effect deps | React stuck ref | kb/case_11.md |
| "expected X but nothing was raised", sibling tests stub the method | Same-file stub leak | kb/case_12.md Pattern E |
waitFor timeout, button disabled when fireEvent.click fired | Disabled-button click race | kb/case_13.md |
PG::InFailedSqlTransaction during synchronous worker + browser poll | Thread-unsafe SET ROLE race | kb/case_15.md |
If no signature matches, investigate from first principles using the
failure report MHTMLs and spec file. After fixing, decide whether to
create a new case file or add a pattern to an existing one (see
kb/README.md step 5b criteria).
Start the session on Sonnet (default). If classification matches a known pattern in the table above, Sonnet is sufficient for applying the documented fix.
If the failure doesn't match any known pattern and requires deep
investigation (reading multiple files, tracing call chains, analysing
backtraces across gems), suggest:
"This is an unfamiliar pattern — recommend switching to Opus
(/model opus) for the investigation."
Before switching back to Sonnet after fixing an unfamiliar case, materialise all learnings to files first:
/model sonnet) for the next test."Why: context compaction summarises older messages to make room. A long Opus investigation accumulates detail that compaction will discard. Writing the case file and JIRA comment while the full context is live preserves the high-fidelity diagnosis. After that, even if compaction occurs on switch-back, the knowledge is safely in the KB.
# flaky-fix: QE-NNN inline on the it linecustom_timeout after adding waitsFull conventions: kb/style.md
Grade a single Canvas request test (`it` block) against the Canvas request-test rules. Returns a pass/fail grade and the list of failing rules with fixes. Report-only — no edits made.
Convert Canvas controller specs (spec/controllers/*) into request specs by rewriting action-based calls to URL-based calls. Use this when migrating a *_controller_spec.rb to the request style (`type: :request`). After the mechanical port, the skill enters Grading mode by default — pass `--no-grading` to skip.
Use this skill to write a single Rails request test for Canvas LMS from a Given/When/Then user scenario. The skill enforces opinionated rules to write readable, isolated, thorough, explicit tests that assert behavior over implementation.
Audit a directory of Canvas selenium tests, classify each `it` block (KEEP / DELETE / PARTIAL / WRITE NEW), verify whether equivalent lower-level coverage already exists, and emit a CSV that a downstream code-modification skill can act on. Use when the user asks to trim, prune, audit, or migrate selenium tests in a specific directory.
Extract behavioral contracts (Given/When/Then) from Selenium `it` blocks. Accepts a spec file, directory, or manual_review.csv. Output CSV is consumed by selenium-coverage-quality to score assertion-level coverage.
Run a selenium spec directory twice — once on the current branch, once with files restored from a base ref — and produce a line-level coverage diff. Use after selenium-trim to verify that deleted tests provided no unique coverage. Also useful standalone to baseline coverage before starting a trim pass.