Fix release for 1.1.1: the minimal path end to end, engine commands that run on Godot, Unity and Unreal, hook warnings you can see, and verdicts that say when they could not check. Details in CHANGELOG.md; upgrade steps in UPGRADING.md (v1.1.1 → v1.1.2). Fixes #67 Fixes #131 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
9.9 KiB
Skill Test Spec: /test-flakiness
Skill Summary
/test-flakiness finds flaky tests from the results of multiple CI or local
test runs. It takes a log path, scan (all available result files — JUnit XML
from gdUnit4 in reports/ or saved into test-results/, NUnit XML from Unity in
test-results/, Unreal automation logs in Saved/Logs/), or registry (remediation guidance for tests already in the
quarantine section of tests/regression-suite.md). With no result data it lists
three ways to get some and stops to ask. It builds a per-test history across
runs, classifies each test that both passed and failed by fail rate — >25% High
(quarantine immediately), 5–25% Moderate (fix directly, do not quarantine yet),
1–5% Low (monitor) — and names a likely cause and fix direction from its cause
table, using Grep on the test file. With fewer than 3 runs, every finding is
"suspected", not "confirmed", whatever its fail rate, and nothing is quarantined;
the summary table's Confidence column says which. It asks separately "May I update the quarantine
section of tests/regression-suite.md…?" and "May I write a full flakiness
report to production/qa/flakiness-report-[date].md?", appends quarantine
entries without removing existing ones, and never deletes test files. No
director gates are invoked. Verdicts: COMPLETE (report written) or BLOCKED
(user declined write).
Static Assertions (Structural)
Checked against the SKILL.md by /skill-test spec — no fixture needed.
- Has required frontmatter fields:
name,description,argument-hint,user-invocable,allowed-tools - Has ≥2 phase headings
- Contains verdict keywords: COMPLETE, BLOCKED, and the flakiness tiers High / Moderate / Low
- Contains "May I" write language for
tests/regression-suite.mdandproduction/qa/flakiness-report-[date].md - Has a next-step handoff (Section 7: add skip annotations, schedule fixes before the release gate)
Director Gate Checks
None. Flakiness detection is an advisory quality skill; no gates are invoked.
Test Cases
Case 1: Happy Path — High flakiness from JUnit history, quarantined on approval
Fixture:
project.yaml:engine.name: godot;modes.automationunset (collaborative)test-results/holds 6 gdUnit4 JUnit XML files from 6 runs of the same committest_loot_drop_rolls_rare_itemfails in 2 of the 6 runs (33%); the other 40 tests pass in all 6tests/unit/loot/loot_drop_test.gdcallsrandf()with no seedtests/regression-suite.mdhas a Quarantined Tests table with 1 existing entry
Input: /test-flakiness scan
Expected behavior:
- Skill finds the XML files in
test-results/and parses<testcase name=and<failure/<errorentries - Skill builds
test_id → [run1 … run6]and finds one test with both outcomes - 33% is above 25% over 6 runs → High flakiness, Confidence confirmed → quarantine immediately
- Grep of
loot_drop_test.gdfindsrandf→ likely cause Random seed; fix direction: pass an explicit seed - The quarantine recommendation names gdUnit4's GDScript skip parameters (
_do_skip := true,_skip_reason := "flaky: ...") as the way to skip it - Summary shows Runs analysed 6, Tests tracked 41, the flaky test with a 33% fail rate, and 40 tests with consistent results
- Skill asks "May I update the quarantine section of
tests/regression-suite.mdwith the flaky tests found?" and, separately, "May I write a full flakiness report toproduction/qa/flakiness-report-[date].md?" - On approval, the new entry is appended with
Edit; the existing entry stays - Verdict: COMPLETE — flakiness report written
Assertions:
- JUnit XML results in
test-results/are parsed per test across all 6 runs - The flaky test is named with its fail rate, Confidence confirmed, and classified High → quarantine
- The skip mechanism named is gdUnit4's
_do_skip/_skip_reasonparameter pair, not an invented flag - The likely cause is Random seed, with the explicit-seed fix direction
- The two writes are asked about separately, each before it happens
- The quarantine entry is appended and the existing entry is not removed
- Verdict is COMPLETE
Case 2: Moderate Flakiness — Fix directly, do not quarantine
Fixture:
project.yaml:engine.name: godottest-results/holds 20 JUnit XML files from 20 runs of the same committest_physics_bounce_height_matches_specfails in 3 of 20 runs (15%)- The test asserts
bounce_height == 0.5
Input: /test-flakiness scan
Expected behavior:
- Skill computes a 15% fail rate → Moderate flakiness
- Grep of the test file finds a float equality comparison → likely cause Floating point
- Recommendation: "This test is intermittently unreliable… Do not quarantine yet — fix the test directly", with the fix direction of an epsilon comparison (
is_equal_approx)
Assertions:
- A 15% fail rate is classified Moderate
- The recommendation is to fix directly, not to quarantine
- The cause is Floating point and the fix names an epsilon comparison such as
is_equal_approx
Case 3: No Result Data — List options and stop
Fixture:
- No
test-results/directory, no.github/directory, noSaved/Logs/ - No log path is given
Input: /test-flakiness scan
Expected behavior:
- Skill finds no CI or local result data
- Skill prints "No CI log data found…" with the three options: run the suite at least 3 times and collect logs; save a CI log to
test-results/; run/test-flakiness registry - Skill stops and asks the user which option to pursue
- No flakiness table is produced and nothing is written
Assertions:
- Output states no CI log data was found
- All three options are listed, including
/test-flakiness registry - Skill stops to ask instead of reporting a clean result
- No files are written
Case 4: Too Few Runs — Suspected, not confirmed
Fixture:
project.yaml:engine.name: godottest-results/holds only 2 JUnit XML files, from 2 runs of the same committest_save_roundtrip_preserves_inventorypasses in one run and fails in the other
Input: /test-flakiness scan
Expected behavior:
- Skill parses both files and finds the test with both outcomes — a 50% fail rate
- With fewer than 3 runs, the finding is flagged "suspected", not "confirmed": the summary table's Confidence reads suspected, and the High tier's quarantine-immediately does not apply
- The test is not quarantined; the recommendation is to collect more runs before acting
- Skill asks whether more run data is available
- The Data Limitations section notes that fewer than 5 runs were available, so confidence is low
Assertions:
- The finding is labelled suspected, not confirmed, in the summary table's Confidence column
- The 50% fail rate does not trigger quarantine — no skip is recommended, and any regression-suite note marks the test suspected
- Skill asks whether more run data is available
- Data Limitations states that fewer than 5 runs were analysed
Case 5: Registry Mode in Full Review Mode — Guidance for known quarantined tests, no gates
Fixture:
project.yaml:modes.review_mode: fulltests/regression-suite.mdQuarantined Tests table liststest_ai_path_recalc_avoids_blocked_tile(reason: timing) andtest_scene_load_spawns_player(reason: scene not ready)
Input: /test-flakiness registry
Expected behavior:
- Skill reads the quarantine section of
tests/regression-suite.md - For each quarantined test it gives remediation guidance from the cause table: Timing / async → explicit await or synchronisation instead of time-based delays; Scene/prefab load race → await one frame after instantiation (
await get_tree().process_frame) - No director gate is invoked regardless of review mode
- Existing quarantine entries are not removed and no test file is deleted or edited by the skill
Assertions:
- The quarantine section of
tests/regression-suite.mdis the input - Each quarantined test gets a fix direction matching its cause
- No director gate is invoked in any review mode
- No quarantine entry is removed and no test file is deleted
Protocol Compliance
- Locates result data (
test-results/XML,Saved/Logs/, or a given log path) before analysis; with none, lists the three options and stops to ask - Classifies tests with both outcomes by fail rate: >25% High (quarantine), 5–25% Moderate (fix, do not quarantine), 1–5% Low (monitor)
- Names a likely cause and fix direction from the cause table, using Grep on the test file
- Counts a test as flaky only when it both passed and failed across runs with no code change between them
- With fewer than 3 runs, flags findings as suspected, not confirmed, in the summary's Confidence column, and quarantines nothing
- Asks separately before updating
tests/regression-suite.mdand before writingproduction/qa/flakiness-report-[date].md - Appends quarantine entries, never removes existing ones, and never deletes test files
- No director gates are invoked
- Ends with COMPLETE on write or BLOCKED on decline; with no result data it lists the three options and stops to ask instead (Case 3), never reporting a clean result
Coverage Notes
- The no-argument path (run
scanwhen CI logs are accessible, elseregistry) is not tested here. - Unity NUnit XML follows the same flow as Case 1, read from
<test-caseelements and theirresultattribute; not tested separately. - Unreal differs and is not tested here: its results are plain-text
Result={Success}/Result={Fail}lines inSaved/Logs/(each test printsTest Completed. Result={<status>}), and its skip mechanism is NOT SOURCEABLE, so a quarantined Unreal test is logged and the user is asked how their CI excludes it. The same applies to gdUnit4 C# tests. - The Low tier (1–5%) needs 20 or more runs to reach and is not tested.