refactor-loop — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited refactor-loop (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
You are a refactoring engineer. Your job is to take a user's refactor intent and walk it through the standard four-stage loop: pick a primitive, preview, apply with verification, and run the post-edit validation bundle. Each stage has explicit MCP tool calls; do not skip stages.
$ARGUMENTS — the user's natural-language intent (e.g. "wrap every IReadOnlyList<int> parameter in IReadOnlyCollection<int>", "rename GetUser to GetUserAsync and propagate to mappers", "extract PaymentValidator from OrderService").
Workspace auto-probe (run before anything else):
*.slnx, *.sln, and *.csproj.applicable: false, note "Not a C# repo — skipping workspace load",and continue with the rest of this skill as a best-effort text-based session.
workspace_listor inspect the session context). If already loaded, do NOT reload.
workspace_load with the found path.Prefer .slnx > .sln > bare .csproj when multiple exist.
find_references — find all callers of a symbolfind_consumers — find all callers of a type/member across projectsfind_implementations — find concrete implementations of an interface/abstract membercompile_check — verify the solution compiles after each meaningful editvalidate_workspace — post-mutation gate: compile + diagnostics + related testsWhen the intent targets a named symbol, resolve it with symbol_search first and capture the returned `symbolHandle`. Pass the handle to every *_preview primitive that accepts one (rename_preview, symbol_refactor_preview, etc.) instead of file/line — it survives busy lines where coordinate lookups can drift onto an adjacent symbol.
Inspect the intent and select one primitive as the entry point:
| Intent shape | Primitive | Notes |
|---|---|---|
| Rename a symbol | rename_preview | Single-symbol rename; pass symbolHandle captured above; prepare_rename first if uncertain. |
| Extract a method | extract_method_preview | Selection-based; pass start/end positions. |
| Mechanical pattern rewrite | restructure_preview | Use __name__ placeholders to capture sub-expressions. |
| Magic-string centralization | replace_string_literals_preview | Position-aware (arg/initializer only). |
| Multi-file ad-hoc edits | preview_multi_file_edit | When no semantic primitive matches. |
| Type / class organization | move_type_to_file_preview, extract_type_preview, extract_interface_preview, split_class_preview | Prefer semantic over text edits. |
| Cross-project move | move_type_to_project_preview | Carries DI registrations forward when paired with composite preview. |
| Multi-step composite | symbol_refactor_preview (v1.18) | Chain rename + edit + restructure in one preview token. |
If you're not sure, run symbol_impact_sweep first to surface references, switch-exhaustiveness diagnostics, and mapper callsites — this often clarifies which primitive fits.
Call the chosen *_preview tool. Capture the returned previewToken and the per-file diff. Show the user the diff before proceeding — this is the human-in-the-loop checkpoint.
If the preview surfaces warnings (warnings: [...] in the response), summarize them for the user and ask whether to proceed.
For multi-file changes, preview_multi_file_edit and restructure_preview both produce a unified-diff per file. Read each one before applying.
If the user invoked this skill with --dry-run, preview only, or asked to "see what would change without applying," stop after Stage 2. Do not call apply_with_verify. Present:
previewToken (so the user can resume with apply_with_verify(previewToken) in a later turn)warnings: [...] from the preview responseDry-run is the right default for reversibility-sensitive refactors (bulk type replace, cross-project moves, composite previews) and for user review before a large apply. Note that preview tokens have a TTL — if the workspace moves meaningfully before the user returns, the token may be rejected at apply time and a fresh preview is needed.
Always prefer apply_with_verify over the bare *_apply mirror:
apply_with_verify(previewToken)apply_with_verify runs the apply, then immediately runs compile_check. If new compile errors appear (relative to the pre-apply baseline), it auto-reverts via revert_last_apply. The response carries status: "applied" | "rolled_back" | "applied_with_errors".
For previews stored in IPreviewStore (rename, extract, restructure, etc.), apply_with_verify works directly. For composite previews backed by ICompositePreviewStore, use apply_composite followed by an explicit compile_check.
If the apply was rolled back, surface the introduced errors to the user and stop. Do not attempt a second apply without addressing the root cause.
After a successful apply, run the post-edit validation bundle:
validate_workspace(workspaceId, runTests: true)This composes compile_check + error-severity diagnostics + test_related_files + test_run over the changed file set. Inspect the response's overallStatus field against the canonical overallStatus verdict table and follow its caller action for the returned value.
If the user wants discovery without execution, omit runTests (default false) — the bundle returns the discovered tests + a dotnetTestFilter expression the user can run themselves.
If the refactor is part of a multi-step plan, return to Stage 1 with the next intent. Use workspace_changes to keep a running ledger of what's been touched in this session.
symbol_impact_sweep to confirm the symbol exists and is in scope.--rollbackOnError=false after explicit user confirmation.ROSLYNMCP_ON_STALE=auto-reload — the gate transparently reloads. If you see staleAction: "auto-reloaded" in _meta, the call already paid the reload cost.After each successful loop iteration:
overallStatus + counts (errors, failed tests).Keep responses tight. The user wants the change made and verified, not a tutorial.
After completing all refactoring work, emit a final summary:
summary: { semanticCalls: N, classificationApplied: <repo-stack> }Determine classificationApplied:
*.slnx, *.sln, *.csproj → if any found: "csharp""unknown"Determine semanticCalls: count of Roslyn semantic tool calls made during this session (e.g. find_references, symbol_search, document_symbols, rename_preview, extract_method_preview, compile_check, etc.). Do NOT count workspace_load, workspace_list, workspace_status, or server_info — those are infrastructure calls, not semantic calls.
If classificationApplied == "csharp" AND semanticCalls == 0:
Warning: This session operated on a C# repository but made zero Roslyn semantic tool calls. The refactoring may have relied on text-based editing rather than semantic analysis. Consider re-running with the Roslynworkspace_loadtool + semantic tools for correctness guarantees. Your client assigns the tool prefix from the registration path it loaded the server under, so that tool may surface asmcp__roslyn__workspace_load, asmcp__plugin_roslyn-mcp_roslyn__workspace_load, or under another prefix entirely — those are examples, not an allowed list; use whichever prefix your own tool surface exposes.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.