Getting it into your agent
One page per mod, every tool's command on it. A separate URL per tool would split the same page into five that compete with each other.
npx skills add joslat/maf-doctor --skill maf-remediation-playbookgit clone --depth 1 https://github.com/joslat/maf-doctorWrote this? Show the measurements
A badge with what this costs and how it scanned, read live from this page, so it follows the numbers instead of freezing them. Markdown for a README, HTML for a documentation site or a project page.
[](https://agentmods.dev/skills/joslat/maf-doctor/maf-remediation-playbook)<a href="https://agentmods.dev/skills/joslat/maf-doctor/maf-remediation-playbook"><img src="https://agentmods.dev/badge/skills/joslat/maf-doctor/maf-remediation-playbook/github.svg" alt="Measured on agentmods" height="20"></a>Or the 80×15 button, for a site that already has a row of RSS and ATOM ones. Only the verdict fits; the numbers stay here.
<a href="https://agentmods.dev/skills/joslat/maf-doctor/maf-remediation-playbook"><img src="https://agentmods.dev/badge/skills/joslat/maf-doctor/maf-remediation-playbook.svg" alt="Reviewed on agentmods" width="80" height="20"></a>What it costs to keep this loaded
Counted locally with the o200k_base tokenizer, which is exact for GPT models; Claude uses its own tokenizer and its counts differ. Treat this as one consistent yardstick across the catalogue rather than a bill. Prices are per million input tokens.
| Model | Per session | Once invoked |
|---|---|---|
| Fable 5.1 | $0.00063 | $0.01624 |
| Opus 5 | $0.00032 | $0.00812 |
| Sonnet 5 | $0.00013 | $0.00325 |
| Haiku 4.5 | $0.00006 | $0.00162 |
Grade A, and why
maf-remediation-playbook scanned grade A with 0 findings against 26 rules in 11 categories — prompt injection, anti-refusal, data exfiltration, privilege escalation, supply chain, agent snooping, system-prompt leakage, SSRF and excessive agency — measured 12d ago.
A static scan of the body, not an audit. Every finding is printed with the line that produced it so you can judge whether it matters here. A mod is markdown that instructs an agent; that is exactly why what it instructs is worth reading.
Nothing flagged
None of the 26 patterns this scan looks for appear in this file: no shell pipes, no recursive deletes, no credential paths, no hidden text, no instruction-override or anti-refusal phrasing, no agent-config snooping. That is not a guarantee, it is the absence of the things that are checkable.
How it starts
The opening of the file, as written. The whole thing — 50 lines — stays where its author put it; the contents beside it link to each section on GitHub.
maf-remediation-playbook — fix real issues, skip false positives
Used by the
maf-remediateprompt. It drives the loop; this skill is the per-rule reference: what the canonical fix is, and — for the heuristic detectors — how to recognise a false positive before you touch code.
The loop (quick reference)
MafDoctor(repoPath, format: "plan")+MafDoctor(repoPath, format: "json", full: true)— the plan + every finding with aconfidence.MafAutoFixAll(repoPath, dryRun: false)— the deterministic, mechanical fixes (F-11:dryRunnow defaults totrue/preview-only; omitting it here would silently apply nothing).dotnet build(green).- For each remaining finding in plan order: triage by
confidence(below) → fix or skip →dotnet build→ confirm the finding actually cleared (re-scan), not just a green build. - Re-pull
MafDoctor(format: "json", full: true)(line numbers shift after edits) and keep working findings until the only ones left are explicitly skipped (false positive) or deferred to human judgment — NOT merely until the A/B/C/F letter stops moving (the grade has wide bands and won't shift for most single fixes). Report fixed vs skipped-as-false-positive.
Confidence tiers (the triage signal)
Every finding carries confidence:
certain— compiler ground-truth (CS0618). No false positives. Fix it.high— structural AST rule, low false-positive risk. Apply the canonical fix with a quick sanity check.heuristic— name-only / text / scope-limited. May be a false positive. CallMafExplainFinding(repoPath, file, line), read the surrounding code, and confirm it's a real problem before changing anything. When unsure after reading the code — in either mode — skip and flag for human review; never edit on a maybe.
Per-rule playbook
| Rule | Confidence | Canonical fix | If it's a FALSE POSITIVE (skip) |
|---|---|---|---|
| MAF001 (fan-out starvation) | high | Return ValueTask<T> — the value is auto-broadcast; required on an AddFanOutEdge source (SendMessageAsync does NOT broadcast on a fan-out edge). For a plain AddEdge target, await context.SendMessageAsync(...) is also valid. |
Rarely a false positive. The source-level detector already treats any handler that emits via context.SendMessageAsync/YieldOutputAsync/AddEventAsync as OK, so a MAF001 finding means the handler returns nothing and emits nothing — a genuine dead-end. (The fan-out-EDGE nuance — a SendMessageAsync-only handler that happens to sit on an AddFanOutEdge source — is resolved cross-file by MafSimulateWorkflow, not by MAF001.) |
| MAF-AP-EXEC-001 (legacy executor) | high | Delete [StreamsMessage]/[YieldsMessage]; migrate ReflectingExecutor<> → sealed partial : Executor + [MessageHandler]. |
An IMessageHandler<T> that is MediatR / NServiceBus / a hand-rolled bus (no Microsoft.Agents.AI.Workflows). |
| MAF-AP-DEVUI-001 (DevUI/Hosting) | high | Wrap the unsupported preview reference in #if DEVUI_ENABLED. |
A supported Microsoft.Agents.AI.Hosting.A2A[.AspNetCore] using, or a project's own namespace DevUI;. |
| MAF-AP-SEC-001 (DefaultAzureCredential) | high | ManagedIdentityCredential in production. |
Already inside an env.IsDevelopment() / #if DEBUG dev-only branch. |
| MAF-AP-SEC-003 (EnableSensitiveData) | high | Make it env-driven (= env.IsDevelopment()) or fence behind #if DEBUG. |
Same-named bool on an unrelated (non-OTel) type. |
| MAF-AP-CONC-001 (provider field) | high | Move per-session state into a readonly ProviderSessionState<T>. |
The field already IS ProviderSessionState<T>, or an injected readonly dependency. |
MAF-AP-CONC-002 (.Result/.Wait()) |
high | Make the chain await-first; propagate async + a CancellationToken. |
(await x).Result (AgentResponse payload) or Match.Result(...) (Regex) — not a blocking Task. |
| MAF-AP-AGENT-001 (top-level Instructions) | high | Move Instructions into the nested ChatOptions (top-level was removed in 1.3.0). |
A user type named ChatClientAgentOptions in your own namespace. |
| MAF-AP-WF-001 (sealed Executor) | high | Add sealed partial to the concrete Executor. |
A non-MAF base type that happens to be named Executor. |
| COST-001 (uncapped agent call) | heuristic | Set MaxOutputTokens on the nearest ChatOptions. |
app.RunAsync() (ASP.NET host), InProcessExecution.RunStreamingAsync/workflow.RunAsync (workflow runners) — not agent calls. |
| MAF-AP-SEC-002 (hard-coded key) | heuristic | Source the key from env/Key Vault; rotate the leaked one. | A non-secret string that merely starts with sk- (a SKU id, slug, or sk-xxxx placeholder). |
| MAF-AP-OBS-001 (no OpenTelemetry) | heuristic | Chain .AsBuilder().UseOpenTelemetry(...) on the client/agent. |
The IChatClient is instrumented in another file and injected here. |
| MAF-AP-MID-001 (middleware) | heuristic | Provide both runFunc: and runStreamingFunc: (or the sharedFunc: overload). |
A non-MAF builder whose Use(runFunc:) has no streaming concept. |
| PROMPT-001/002/003/004 (prompt lint) | heuristic | Non-empty prompt; split bloat; add refusal guidance; never interpolate untrusted input into Instructions. | An Instructions property on a non-agent type (recipe, build step, form field). |
What this file has done since we first saw it
Hashed on every crawl. A supply-chain change to an agent config is a question of when, not whether, so the history is kept rather than the latest state alone.
- 12d ago First seen · 50 lines · 63 tokens per session scan A 8d3e6cff6c06
maf-remediation-playbook is a skill published in the GitHub repository joslat/maf-doctor (14 stars, last pushed 25d ago), licensed MIT. It adds 63 tokens to every session and 1,624 once invoked, about $0.0003 per session on Opus 5. A static security scan graded it A with 0 findings. No closer match exists in the catalogue, so it is treated as the original; first seen 2026-08-30.
Other skills, from other repositories
winui-session-report
Analyze the current or a recent agent session (GitHub Copilot CLI or Claude Code) and generate a diagnostic report. Use only when the user explicitly asks for session feedback, agent debugging, or a review of what happened during a build session. Do not inspect session data automatically.
chrome-devtools-mcp
Use Chrome DevTools MCP from .NET agents and .NET-focused repos to inspect, debug, and automate Chrome through an MCP client. USE FOR: the repo needs browser-level debugging for ASP.NET Core, Blazor, WebAssembly, or any .NET app with a web UI; the user wants an MCP server that can inspect console. DO NOT USE FOR: pure…
managedcode-orleans-graph
Integrate ManagedCode.Orleans.Graph into an Orleans-based .NET application for grain-call policy enforcement, deadlock detection, live-call telemetry, and Mermaid graph diagnostics. USE FOR: ManagedCode.Orleans.Graph integration; allowed grain transitions; Orleans call filters; live policy graphs; reviewing Orleans…
asynkron-profiler
Use the open-source free Asynkron.Profiler dotnet tool for CLI-first CPU, allocation, exception, contention, and heap profiling of .NET commands or existing trace artifacts. USE FOR: Asynkron.Profiler setup; automation-friendly profiling output; CPU, allocation, exception, contention, and heap investigation. DO NOT…
profiling
Use the free official .NET diagnostics CLI tools for profiling and runtime investigation in .NET repositories. USE FOR: the repo needs performance or runtime profiling for a .NET application; the user asks about slow code, high CPU, GC pressure, allocation growth, exception storms, lock. DO NOT USE FOR: replacing…
component-flattening-analysis
Detects misplaced classes and fixes component hierarchy problems — finds code that should belong inside a component but sits at the root level. Use when asking "clean up component structure", "find orphaned classes", "fix module hierarchy", "flatten nested components", or analyzing why namespaces have misplaced code.…