Remediation Options Skill
Purpose
Provides standardized remediation workflow for config violations, presenting three consistent options with intelligent recommendations based on repository type.
The 3-Option Pattern
When config violations are detected, ALWAYS present exactly 3 options:
- Conform to template - Make repository match agent standard
- Ignore - Skip this violation (acceptable for library repos)
- Update template - Evolve the standard to match repository
Option Details
Option 1: Conform to Template
What it does:
- Overwrites existing config with standard template
- Re-audits automatically after changes
- Most common choice for consumer repos
When recommended:
- Consumer repositories (strict standards)
- First-time setup
- Standardizing across multiple packages
Implementation:
async function conformToTemplate(
configPath: string,
configType: string,
): Promise<void> {
// 1. Load template
const template = await loadTemplate(configType);
// 2. Backup existing (optional)
await backupConfig(configPath);
// 3. Write template
await writeFile(configPath, template);
// 4. Create additional required files
await createRequiredFiles(configType, configPath);
// 5. Re-audit to verify
const auditResult = await runAudit(configType, configPath);
if (auditResult.passing) {
console.log("✅ Config now conforms to standard");
} else {
console.log("⚠️ Some issues remain after conforming");
}
}
Option 2: Ignore
What it does:
- Skips this violation
- No changes made
- Violation remains in future audits
When recommended:
- Library repositories (intentional differences)
- Temporary exceptions
- Edge cases being evaluated
Implementation:
async function ignoreViolation(
violation: string,
reason?: string,
): Promise<void> {
console.log(`
ℹ️ Violation ignored: ${violation}
${reason ? ` Reason: ${reason}` : ""}
This violation will appear in future audits unless:
- The config is fixed
- An exception is declared in package.json
`);
// Optionally: Store in memory for reporting
await storeIgnoredViolation(violation, reason);
}
Option 3: Update Template
What it does:
- Updates agent's template to match current repo config
- Evolves the standard for all consumer repos
- Re-audit all consumer repos recommended after
When recommended:
- Evolving standards across organization
- New best practice discovered
- Template is outdated
CRITICAL: Only for consumer repos - library repos are NOT the source of truth for consumer standards
Implementation:
async function updateTemplate(
configType: string,
newConfig: any,
reason: string,
): Promise<void> {
// 1. Confirm with user (this affects all repos)
const confirmed = await confirmTemplateUpdate({
configType,
reason,
impact: "All consumer repos will use this new standard",
});
if (!confirmed) {
console.log("❌ Template update cancelled");
return;
}
// 2. Update template
const templatePath = `.claude/templates/common/${configType}`;
await writeFile(templatePath, newConfig);
// 3. Document change
await documentTemplateChange(configType, reason);
// 4. Recommend re-audit
console.log(`
✅ Template updated: ${templatePath}
⚠️ RECOMMENDED: Re-audit all consumer repos to verify consistency
Run: /ms "audit all ${configType} configs across consumer repos"
`);
}
Presentation Format
Standard Output Template
function presentRemediationOptions(
repoType: string,
configType: string,
violations: string[],
): string {
const recommendation = getRecommendation(repoType);
return `
──────────────────────────────────────────────
Remediation Options:
──────────────────────────────────────────────
1. Conform to template (fix ${configType} to match standard)
${getOption1Details(configType)}
2. Ignore (skip for now)
3. Update template (evolve the standard)
💡 Recommendation: ${recommendation.option} (${recommendation.label})
${recommendation.reason}
Your choice (1-3):
`;
}
Option 1 Details by Config Type
function getOption1Details(configType: string): string {
const details = {
eslint: "→ Overwrites .eslintrc.js\n → Re-audits automatically",
prettier: "→ Overwrites .prettierrc\n → Re-audits automatically",
typescript:
"→ Overwrites tsconfig.json\n → Verifies extends paths\n → Re-audits automatically",
vitest:
"→ Overwrites vitest.config.ts\n → Creates ./vitest.setup.ts if frontend package\n → Re-audits automatically",
tailwind:
"→ Overwrites tailwind.config.js\n → Creates src/index.css if missing\n → Re-audits automatically",
};
return (
details[configType] || "→ Overwrites config\n → Re-audits automatically"
);
}
Smart Recommendations
Based on Repository Type
interface Recommendation {
option: number; // 1, 2, or 3
label: string; // "Conform to template" | "Ignore" | "Update template"
reason: string;
emoji: string;
}
function getRecommendation(repoType: string): Recommendation {
if (repoType === "library") {
return {
option: 2,
label: "Ignore",
reason:
"Library repo (@metasaver/multi-mono) is intentionally different.",
emoji: "⭐",
};
}
// Consumer repo
return {
option: 1,
label: "Conform to template",
reason: `Consumer repos should follow standard ${configType} configuration.`,
emoji: "💡",
};
}
Based on Violation Severity
function getRecommendationBySeverity(
severity: "critical" | "warning" | "info",
repoType: string,
): Recommendation {
if (severity === "critical") {
// Critical violations: Always conform (even library repos should consider)
return {
option: 1,
label: "Conform to template",
reason: "Critical violation affects functionality or security.",
emoji: "🚨",
};
}
if (severity === "warning" && repoType === "consumer") {
return {
option: 1,
label: "Conform to template",
reason: "Consumer repos should address warnings for consistency.",
emoji: "💡",
};
}
// Info-level or library repo: Ignore is acceptable
return {
option: 2,
label: "Ignore",
reason:
repoType === "library"
? "Library repo differences are expected."
: "Low-priority issue, can be addressed later.",
emoji: "ℹ️",
};
}
User Interaction Pattern
Using AskUserQuestion Tool
async function promptUserForRemediation(
repoType: string,
configType: string,
violations: string[],
): Promise<number> {
const recommendation = getRecommendation(repoType);
const answer = await AskUserQuestion({
questions: [
{
question: `${violations.length} violation(s) found in ${configType}. How would you like to proceed?`,
header: "Remediation",
multiSelect: false,
options: [
{
label: "Conform to template",
description: `Fix ${configType} to match MetaSaver standard`,
},
{
label: "Ignore for now",
description: "Skip this violation (will appear in future audits)",
},
{
label: "Update template",
description: "Evolve the standard to match current config",
},
],
},
],
});
const choices = {
"Conform to template": 1,
"Ignore for now": 2,
"Update template": 3,
};
return choices[answer.Remediation];
}
Handling User Choice
async function executeRemediationChoice(
choice: number,
context: RemediationContext,
): Promise<void> {
const { repoType, configType, configPath, violations } = context;
switch (choice) {
case 1: // Conform
console.log(`\n🔧 Con