scripts-reset-skill-learnings-baseline
#!/usr/bin/env python3 """
title: Reset Skill Learnings Baseline component_type: script version: 1.0.0 audience: contributor status: active summary: Reset inflated anti-pattern counts and historical noise in skill-learnings.json keywords:
- calibration
- reset
- baseline
- skill-learnings created: 2026-01-13
Reset the skill-learnings.json baseline to clear inflated anti-pattern counts caused by overly broad pattern matching. Preserves actual skill performance data (success/failure counts) while clearing noise.
Usage: python3 scripts/reset-skill-learnings-baseline.py # Preview changes python3 scripts/reset-skill-learnings-baseline.py --apply # Apply reset python3 scripts/reset-skill-learnings-baseline.py --backup # Create backup first """
import argparse import json import shutil from datetime import datetime from pathlib import Path
def reset_skill_learnings(coditect_root: Path, apply: bool = False, backup: bool = True): """Reset the skill learnings baseline.""" # ADR-114 & ADR-118: Use centralized path discovery import sys sys.path.insert(0, str(coditect_root / "scripts" / "core")) try: from paths import get_context_storage_dir, CONTEXT_STORAGE context_dir = get_context_storage_dir() except ImportError: # Fallback for backward compatibility _user_data = Path.home() / "PROJECTS" / ".coditect-data" / "context-storage" if _user_data.exists(): context_dir = _user_data else: context_dir = coditect_root / "context-storage"
learnings_file = context_dir / "skill-learnings.json"
if not learnings_file.exists():
print("No skill-learnings.json found. Nothing to reset.")
return
# Load current data
with open(learnings_file, 'r') as f:
data = json.load(f)
print(f"Current file size: {learnings_file.stat().st_size / 1024:.1f} KB")
print(f"Sessions tracked: {len(data.get('sessions', []))}")
print(f"Skills tracked: {len(data.get('skill_history', {}))}")
print(f"Anti-patterns tracked: {len(data.get('anti_pattern_trends', {}))}")
# Calculate current anti-pattern totals
total_anti_patterns = 0
for name, trend in data.get('anti_pattern_trends', {}).items():
count = trend.get('total_occurrences', 0)
total_anti_patterns += count
if count > 1000: # Inflated
print(f" ⚠️ {name}: {count:,} occurrences (likely inflated)")
print(f"\nTotal anti-pattern occurrences: {total_anti_patterns:,}")
if not apply:
print("\n--- PREVIEW MODE ---")
print("Add --apply to execute reset")
print("Add --backup to create backup first")
return
# Create backup if requested
if backup:
backup_path = learnings_file.with_suffix(
f".json.bak-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
)
shutil.copy(learnings_file, backup_path)
print(f"\n✅ Backup created: {backup_path.name}")
# Reset the data
reset_data = {
"sessions": data.get("sessions", [])[-20:], # Keep last 20 sessions only
"skill_history": {},
"anti_pattern_trends": {},
"reset_info": {
"reset_at": datetime.now().isoformat(),
"reason": "Baseline reset due to inflated anti-pattern counts from broad pattern matching",
"previous_sessions": len(data.get("sessions", [])),
"previous_skills": len(data.get("skill_history", {})),
"previous_anti_patterns": total_anti_patterns
}
}
# Preserve actual skill success/failure data (verified performance)
for skill_name, history in data.get("skill_history", {}).items():
# Only keep skills with actual invocations
if history.get("total_invocations", 0) > 0:
# Calculate actual success rate from invocations (not inflated)
total = history.get("total_invocations", 0)
success = history.get("success_count", 0)
failed = history.get("failed_count", 0)
# Only include if we have meaningful data
if total >= 1 and total < 10000: # Exclude obviously inflated
reset_data["skill_history"][skill_name] = {
"total_invocations": min(total, 100), # Cap at reasonable number
"success_count": min(success, 100),
"failed_count": min(failed, 100),
"score_history": history.get("score_history", [])[-5:], # Last 5 scores
"common_errors": history.get("common_errors", [])[:3] # Top 3 errors
}
# Write reset data
with open(learnings_file, 'w') as f:
json.dump(reset_data, f, indent=2)
new_size = learnings_file.stat().st_size
print(f"\n✅ Reset complete")
print(f"New file size: {new_size / 1024:.1f} KB")
print(f"Sessions kept: {len(reset_data['sessions'])}")
print(f"Skills preserved: {len(reset_data['skill_history'])}")
print(f"Anti-patterns cleared: {total_anti_patterns:,} → 0")
def main(): parser = argparse.ArgumentParser( description="Reset skill-learnings.json baseline" ) parser.add_argument( "--apply", action="store_true", help="Apply the reset (without this flag, only preview)" ) parser.add_argument( "--backup", action="store_true", help="Create backup before reset" ) parser.add_argument( "--root", default=Path(file).parent.parent, type=Path, help="CODITECT root directory" )
args = parser.parse_args()
reset_skill_learnings(args.root, apply=args.apply, backup=args.backup)
if name == "main": main()