dotnet

ci-fix

Common safety and triage protocol for .NET MAUI CI-fixer workflows. Use whenever investigating, creating, or advancing a `[ci-fix]` or `[ci-fix-net11]` pull request from a `ci-scan` issue, including frozen ownership snapshots, Continue/Watch/Stop/Skip classification, manual single-issue dispatches, and scheduled sweeps.

dotnet 23,317 1,965 Updated 3w ago

Resources

1
GitHub

Install

npx skillscat add dotnet/maui/ci-fix

Install via the SkillsCat registry.

SKILL.md

CI-fix triage protocol

Use this protocol before proposing a code change or emitting a CI-fixer safe
output. The calling workflow supplies its branch, labels, title prefix, attempt
limit, and allowed write surface; preserve those caller-specific restrictions.

Return a decision

For each candidate, state one terminal decision before taking an action:

  • Decision: Continue — no dedup or safety gate blocks current-evidence analysis.
  • Decision: Watch — exclusively an open workflow-owned CI-fix PR owns the
    issue; advance only that PR.
  • Decision: Stop — an explicit human PR owns the issue; do not monitor it or
    plan a fallback CI-fix PR.
  • Decision: Skip — the issue is stale, visual, already fixed, out of scope, or
    cannot be safely advanced.

Explain the concrete evidence for the decision. A search result is evidence to
inspect, not a decision by itself.

Reason through all ownership evidence before emitting the decision. Return
exactly one terminal decision; never emit a provisional decision and then
correct it later in the response.

When the caller requests a strict decision format, complete the classification
before writing any response text. Emit only the final decision and requested
next action. Do not include a draft, correction, or alternate decision.

Deduplicate without false ownership

  1. An open CI-fix PR with the workflow's title prefix and exact Refs: dotnet/maui#<issue> is the only Watch case. Never open a second CI-fix
    PR for that issue.
  2. A merged CI-fix PR with that exact reference is a Skip case until current
    evidence establishes a new regression.
  3. A closed-unmerged CI-fix PR with that exact reference is a Skip case. A
    human closing the PR is a stop signal for the keep-one-PR loop.
  4. An open human PR is always a Stop case when its own title or body
    explicitly declares that it addresses the tracking issue. Do not monitor it
    or plan a fallback CI-fix PR. Accept a Refs: declaration or a
    closing/reference keyword such as Fix, Fixes, Fixed, Close, Closes,
    Closed, Resolve, Resolves, or Resolved followed by the issue
    reference, including #<issue>, dotnet/maui#<issue>, or
    https://github.com/dotnet/maui/issues/<issue>.

GitHub search normally includes comments and incidental status text. Do not
treat a raw issue number in a comment, check summary, commit message, diff, or
unrelated list as human ownership. Inspect the PR title and body before stopping.
If every result is incidental, return Decision: Continue; an unrelated search
hit is not independently a reason to Stop or Skip.

Require current, specific evidence

Before a fresh attempt:

  1. Confirm the issue is in the caller's branch and label scope.
  2. Skip screenshot and visual-regression failures; do not modify baselines.
  3. Verify the cited failure still reproduces on the latest completed base-branch
    build. A historical failure alone is not a reason to create a PR.
  4. Trace the exact failing test, platform path, and deepest relevant stack frame.
    Check whether an intervening merged PR already fixed that path before proposing
    a duplicate or adjacent workaround.
  5. Preserve the test's assertion. Do not mute, ignore, retry, weaken, or extend a
    timeout to hide a failure. A legitimate de-flake makes the state transition or
    synchronization deterministic.

Bound autonomous work

Advance only the existing CI-fix PR and respect the caller's effective attempt
counter. When the cap is reached, return Decision: Skip and defer rather than
advancing the existing PR or opening a replacement.
Never claim the target test is fixed from a category-level result or an unrelated
green leg; require evidence for the specific test on the CI-fix PR's current
head.

Fail closed at the write boundary

Before any code-push safe output, apply the caller's transport gate to the saved
base and head. Reject transport unless the saved base is an ancestor, all new
commits are append-only and merge-free, and the complete diff stays within the
caller's allowed paths, commit count, file count, and patch-byte bounds. Never
trim, conceal, or retry an unrelated or oversized diff merely to make it pass.

If a supported safe-output call returns a backend, connection, or validation
error, do not retry that mutation, continue the remaining mutation set, emit a
noop, or use a direct write path. Request one bounded report_incomplete safe
output and stop. A missing expected safe output is a failed/incomplete run, not
a successful no-write result.