
Nav Diagnose
- 2 installs
- 32 repo stars
- Updated January 23, 2026
- dkyazzentwatwa/supernavigator
Detects drops in AI output quality (repeated corrections, hallucinations, context confusion) and prompts re-anchoring to restore collaboration.
About
Detects when human-AI collaboration quality drops and prompts re-anchoring to restore effective communication. A developer relies on it after repeated corrections or context confusion.
- Detects repeated corrections, hallucinations, and context confusion
- Prompts re-anchoring templates to restore collaboration quality
Nav Diagnose by the numbers
- 2 all-time installs (skills.sh)
- Ranked #2,409 of 3,280 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Jul 29, 2026 (Skillselion catalog sync)
npx skills add https://github.com/dkyazzentwatwa/supernavigator --skill nav-diagnoseAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 32 |
| Last updated | January 23, 2026 |
| Repository | dkyazzentwatwa/supernavigator ↗ |
What it does
Detects drops in AI output quality (repeated corrections, hallucinations, context confusion) and prompts re-anchoring to restore collaboration.
Files
Navigator Diagnose Skill
Detect when human-AI collaboration quality drops and prompt re-anchoring to restore effective communication.
Why This Exists (Theory of Mind)
Based on Riedl & Weidmann 2025 research on Human-AI Synergy:
- Theory of Mind varies dynamically within users (moment-to-moment)
- Quality drops occur when ToM alignment degrades
- Early detection and re-anchoring restores collaboration effectiveness
- Both user ToM (understanding Claude) and Claude's model of user can drift
This skill detects when collaboration is degrading and prompts corrective action.
When to Invoke
Auto-invoke when:
- 2+ corrections on the same topic detected
- User says "something seems off", "you're not getting this"
- User says "wrong again", "still not right"
- Context usage exceeds 75% and quality signals degrade
- User expresses frustration ("ugh", "sigh", explicit frustration)
- Loop mode stagnation detected (3+ same-state iterations)
DO NOT invoke if:
- Single correction (normal collaboration)
- User is providing new requirements (not correcting)
- Fresh session (insufficient data to diagnose)
- User explicitly says "it's fine" or "close enough"
Quality Drop Indicators
1. Repeated Corrections (High Severity)
Trigger: Same correction given 2+ times
Signal: "No, I said users plural, not user" (2nd time)
Issue: Not incorporating user feedback2. Hallucination Signals (High Severity)
Trigger: References to non-existent files, functions, or packages
Signal: "That file doesn't exist", "There's no such function"
Issue: Generating from incorrect mental model3. Context Confusion (Medium Severity)
Trigger: Mixing details from unrelated tasks
Signal: "That's from the other project", "Wrong feature"
Issue: Context window pollution or misattribution4. Unaddressed Feedback (Medium Severity)
Trigger: User correction not reflected in next output
Signal: Generates same pattern after being told not to
Issue: Not properly updating internal model5. Goal Drift (Low Severity)
Trigger: Output increasingly diverges from original goal
Signal: "We're getting off track", "Not what I asked for"
Issue: Lost sight of user's actual objective6. Loop Stagnation (High Severity)
Trigger: 3+ consecutive iterations with same state hash (loop mode only)
Signal: nav-loop detects stagnation, triggers nav-diagnose
Issue: Stuck on same step, unable to progressExecution Steps
Step 1: Assess Quality State
Analyze recent exchanges (last 10-15 messages):
Quality Indicators:
- [ ] Corrections given: {count}
- [ ] Same-topic corrections: {count}
- [ ] User frustration signals: {count}
- [ ] Hallucination reports: {count}
- [ ] "Not what I meant" phrases: {count}Calculate severity:
severity = "critical" if same_topic_corrections >= 2 or hallucinations >= 1
severity = "high" if corrections >= 3 or frustration_signals >= 2
severity = "medium" if corrections >= 2 or goal_drift_detected
severity = "low" if corrections == 1 # Normal, don't triggerStep 2: Identify Root Cause
Analyze correction patterns:
| Pattern | Likely Cause | Re-anchoring Focus |
|---|---|---|
| Same correction repeated | Not incorporating feedback | Explicitly acknowledge and confirm understanding |
| Increasing corrections | Drifting from user intent | Re-establish goals |
| Technical mismatches | Wrong assumptions | Clarify technical context |
| Frustration without specifics | Communication mismatch | Ask what's wrong |
Step 3: Display Diagnostic
Show quality check alert:
⚠️ QUALITY CHECK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Detected Issue: {ISSUE_TYPE}
Severity: {SEVERITY}
What I noticed:
- {OBSERVATION_1}
- {OBSERVATION_2}
Possible causes:
- {CAUSE_1}
- {CAUSE_2}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Let me re-anchor our collaboration:
1. Your goal: {RECONSTRUCTED_GOAL}
2. Current state: {STATE_SUMMARY}
3. What you want: {CORRECTED_UNDERSTANDING}
Is this understanding correct? [Y/n]Step 4: Re-anchor Collaboration
Based on user confirmation:
If correct (Y):
✅ Re-anchored!
I'll proceed with this understanding:
- {KEY_POINT_1}
- {KEY_POINT_2}
Continuing with: {NEXT_ACTION}If incorrect (n):
Help me understand better:
1. What is your actual goal?
2. What am I getting wrong?
3. What constraints should I know?
[Open-ended response welcome]Step 5: Log Diagnostic (Optional)
If nav-profile exists, save diagnostic:
{
"date": "{YYYY-MM-DD}",
"issue_type": "{ISSUE_TYPE}",
"severity": "{SEVERITY}",
"resolution": "re-anchored|user-corrected|escalated",
"learnings": ["{WHAT_TO_AVOID}"]
}Step 6: Suggest Preventive Actions
Based on severity and pattern:
For context overload:
💡 Suggestion: Consider running nav-compact to clear context.
Current context usage is high, which can cause confusion.For repeated corrections:
💡 Suggestion: Let me save your preference to avoid this in future.
"Remember I always want {X}" - This will persist across sessions.For communication mismatch:
💡 Suggestion: Consider adjusting your profile preferences.
- Current verbosity: {VERBOSITY}
- Current confirmation: {CONFIRMATION}
Update with: "Remember I prefer {SUGGESTED_STYLE}"---
Re-anchoring Templates
Template 1: Goal Re-alignment
Let me verify I understand your goal:
You want to: {GOAL_STATEMENT}
Not: {COMMON_MISUNDERSTANDING}
Key constraints:
- {CONSTRAINT_1}
- {CONSTRAINT_2}
Is this right?Template 2: Technical Re-alignment
Let me verify the technical context:
Framework: {FRAMEWORK}
Patterns: {PATTERNS}
Conventions: {CONVENTIONS}
What I should be using:
- {TOOL_1}: for {PURPOSE_1}
- {TOOL_2}: for {PURPOSE_2}
Corrections to my assumptions?Template 3: Communication Re-alignment
I may be mismatching your communication style:
You seem to prefer:
- {INFERRED_STYLE_1}
- {INFERRED_STYLE_2}
I've been:
- {MY_STYLE_1}
- {MY_STYLE_2}
Should I adjust my approach?---
Integration with Other Skills
With nav-profile
- Log diagnostics for pattern analysis
- Suggest preference updates after repeated issues
- Load profile preferences for baseline comparison
With nav-marker
- Suggest marker before major re-anchoring
- Include diagnostic state in marker
With nav-compact
- Recommend compact if context overload detected
- Track if compaction resolves issues
---
Quality Signals Reference
Positive Signals (Good Collaboration)
- "Perfect, exactly what I needed"
- "Yes, continue"
- "Good, now..."
- No corrections for 5+ exchanges
- User providing new requirements (not corrections)Negative Signals (Quality Drop)
- "No", "Wrong", "Not that"
- "I already said..."
- "Again, please..."
- "Sigh", "Ugh", explicit frustration
- "You're not understanding"
- Same correction twiceNeutral Signals (Normal Iteration)
- "Actually, let's try..."
- "Can we also..."
- "What about..."
- Single correction with explanation---
Example Scenarios
Scenario 1: Repeated REST Convention Correction
Exchange 1:
User: "Create endpoint for users"
Claude: Creates /user endpoint
User: "Should be /users (plural)"
Exchange 2:
User: "Now create endpoint for posts"
Claude: Creates /post endpoint
User: "Again, plural! /posts"
→ Trigger: Same correction (plural naming) given twice
→ Action: Re-anchor on REST conventions
→ Outcome: "I understand now - always use plural nouns for REST resources"Scenario 2: Context Confusion
User working on: OAuth feature (Feature A)
Claude references: Stripe integration (Feature B from earlier)
User: "That's from the payment feature, not auth"
→ Trigger: Context confusion detected
→ Action: Re-anchor on current feature
→ Suggestion: Consider nav-compact to clear old contextScenario 3: User Frustration
User: "Ugh, still not right"
User: "This is frustrating"
→ Trigger: Frustration signals detected
→ Action: Pause and diagnose
→ Response: Open-ended question about what's wrong---
Success Criteria
Diagnostic is successful when:
- [ ] Quality drops detected before user escalates
- [ ] Root cause correctly identified
- [ ] Re-anchoring restores collaboration quality
- [ ] Preventive suggestions are actionable
- [ ] User confirms understanding after re-anchor
- [ ] Same issue doesn't recur immediately
---
Limitations
Cannot detect:
- Silent user frustration (no signals in text)
- Issues outside conversation context
- Problems with external systems
- User preferences not yet expressed
Should not:
- Over-trigger on normal corrections
- Interrupt productive flow
- Make user feel blamed
- Require lengthy re-explanation
---
Best Practices
When diagnosing:
- Be humble about AI limitations
- Don't blame user for miscommunication
- Offer concrete next steps
- Keep re-anchoring brief
When re-anchoring:
- Focus on understanding, not apologizing
- Confirm specific points, not general "I understand"
- Let user correct if wrong
- Thank user for patience
---
This skill catches collaboration quality drops early, enabling quick recovery through Theory of Mind re-alignment 🔍
#!/usr/bin/env python3
"""
Quality Detector - Detect quality drops in human-AI collaboration
Analyzes conversation patterns to identify when collaboration quality is degrading.
"""
import json
import sys
import argparse
import re
from typing import Dict, List, Optional
from dataclasses import dataclass, asdict
from enum import Enum
class Severity(Enum):
LOW = "low"
MEDIUM = "medium"
HIGH = "high"
CRITICAL = "critical"
class IssueType(Enum):
REPEATED_CORRECTION = "repeated_correction"
HALLUCINATION = "hallucination"
CONTEXT_CONFUSION = "context_confusion"
UNADDRESSED_FEEDBACK = "unaddressed_feedback"
GOAL_DRIFT = "goal_drift"
FRUSTRATION = "frustration"
@dataclass
class QualityIssue:
issue_type: str
severity: str
description: str
evidence: List[str]
suggestion: str
# Frustration signal patterns
FRUSTRATION_PATTERNS = [
r'\bugh\b',
r'\bsigh\b',
r'\bfrustrat(ing|ed)\b',
r'\bannoying\b',
r'\bcome on\b',
r'\bseriously\b',
r'\bwhy (can\'t|won\'t)\b',
r'\bstill (not|wrong)\b',
r'\bagain[,!?]?\s*$',
r'\bi (already|just) (said|told)\b',
]
# Correction signal patterns
CORRECTION_PATTERNS = [
r'\bno,?\s',
r'\bwrong\b',
r'\bnot (that|what|right)\b',
r'\bshould (be|have)\b',
r'\bactually,?\s',
r'\bi meant\b',
r'\bnot (\w+),?\s*(use|it\'s)\b',
r'\bplural\b',
r'\bsingular\b',
]
# Hallucination report patterns
HALLUCINATION_PATTERNS = [
r'\b(that|this) (file|function|module|package|class) (doesn\'t|does not) exist\b',
r'\bthere\'?s no (such|that)\b',
r'\b(file|function|variable) not found\b',
r'\bwhere did you get\b',
r'\bi (don\'t|never) have\b',
r'\bthat\'?s not (in|from|part of)\b',
]
# Context confusion patterns
CONFUSION_PATTERNS = [
r'\bthat\'?s (from|for) (the|a) (other|different|wrong)\b',
r'\bwrong (project|feature|file|context)\b',
r'\bnot (this|that) (one|project|feature)\b',
r'\bwe\'?re (talking|working) (on|about)\b',
r'\bmixing (up|things)\b',
]
# Goal drift patterns
DRIFT_PATTERNS = [
r'\bgetting off track\b',
r'\bnot what i asked\b',
r'\bback to\b',
r'\blet\'?s focus\b',
r'\boriginal(ly)?\b',
r'\bwhat i (actually|really) (want|need)\b',
]
def analyze_message(text: str) -> Dict[str, List[str]]:
"""Analyze a single message for quality signals."""
text_lower = text.lower()
signals = {
'frustration': [],
'correction': [],
'hallucination': [],
'confusion': [],
'drift': [],
}
for pattern in FRUSTRATION_PATTERNS:
if re.search(pattern, text_lower):
signals['frustration'].append(pattern)
for pattern in CORRECTION_PATTERNS:
if re.search(pattern, text_lower):
signals['correction'].append(pattern)
for pattern in HALLUCINATION_PATTERNS:
if re.search(pattern, text_lower):
signals['hallucination'].append(pattern)
for pattern in CONFUSION_PATTERNS:
if re.search(pattern, text_lower):
signals['confusion'].append(pattern)
for pattern in DRIFT_PATTERNS:
if re.search(pattern, text_lower):
signals['drift'].append(pattern)
return signals
def extract_correction_topic(text: str) -> Optional[str]:
"""Try to extract what the correction is about."""
text_lower = text.lower()
# "should be X" pattern
match = re.search(r'should be ["\']?(\w+)["\']?', text_lower)
if match:
return match.group(1)
# "not X, use Y" pattern
match = re.search(r'not (\w+),?\s*(use|it\'s) (\w+)', text_lower)
if match:
return f"{match.group(1)}→{match.group(3)}"
# "plural/singular" pattern
if 'plural' in text_lower or 'singular' in text_lower:
return "naming_convention"
return None
def detect_quality_issues(messages: List[str]) -> List[QualityIssue]:
"""Analyze multiple messages to detect quality issues."""
issues = []
# Aggregate signals across messages
all_signals = {
'frustration': 0,
'correction': 0,
'hallucination': 0,
'confusion': 0,
'drift': 0,
}
correction_topics = []
evidence = []
for msg in messages:
signals = analyze_message(msg)
for signal_type, patterns in signals.items():
if patterns:
all_signals[signal_type] += 1
evidence.append(f"{signal_type}: '{msg[:50]}...'")
if signal_type == 'correction':
topic = extract_correction_topic(msg)
if topic:
correction_topics.append(topic)
# Detect repeated corrections on same topic
topic_counts = {}
for topic in correction_topics:
topic_counts[topic] = topic_counts.get(topic, 0) + 1
repeated_topics = [t for t, c in topic_counts.items() if c >= 2]
# Generate issues based on signals
# Critical: Repeated same correction
if repeated_topics:
issues.append(QualityIssue(
issue_type=IssueType.REPEATED_CORRECTION.value,
severity=Severity.CRITICAL.value,
description=f"Same correction given multiple times: {repeated_topics}",
evidence=[f"Topic '{t}' corrected {topic_counts[t]} times" for t in repeated_topics],
suggestion="Explicitly acknowledge the correction and confirm understanding before proceeding"
))
# Critical: Hallucination detected
if all_signals['hallucination'] >= 1:
issues.append(QualityIssue(
issue_type=IssueType.HALLUCINATION.value,
severity=Severity.CRITICAL.value,
description="Referenced non-existent file, function, or resource",
evidence=[e for e in evidence if 'hallucination' in e],
suggestion="Re-verify file structure and available resources before generating code"
))
# High: Multiple corrections
if all_signals['correction'] >= 3:
issues.append(QualityIssue(
issue_type=IssueType.UNADDRESSED_FEEDBACK.value,
severity=Severity.HIGH.value,
description=f"High number of corrections ({all_signals['correction']})",
evidence=[e for e in evidence if 'correction' in e][:3],
suggestion="Pause and re-establish understanding of user's requirements"
))
# High: Frustration signals
if all_signals['frustration'] >= 2:
issues.append(QualityIssue(
issue_type=IssueType.FRUSTRATION.value,
severity=Severity.HIGH.value,
description="User showing signs of frustration",
evidence=[e for e in evidence if 'frustration' in e],
suggestion="Acknowledge the difficulty and ask what would help"
))
# Medium: Context confusion
if all_signals['confusion'] >= 1:
issues.append(QualityIssue(
issue_type=IssueType.CONTEXT_CONFUSION.value,
severity=Severity.MEDIUM.value,
description="Mixing up context from different tasks or projects",
evidence=[e for e in evidence if 'confusion' in e],
suggestion="Consider using nav-compact to clear old context"
))
# Medium: Goal drift
if all_signals['drift'] >= 1:
issues.append(QualityIssue(
issue_type=IssueType.GOAL_DRIFT.value,
severity=Severity.MEDIUM.value,
description="Output diverging from original goal",
evidence=[e for e in evidence if 'drift' in e],
suggestion="Re-establish the primary goal before continuing"
))
return issues
def format_diagnostic_report(issues: List[QualityIssue]) -> str:
"""Format issues as a diagnostic report."""
if not issues:
return "✅ No quality issues detected"
# Get highest severity
severity_order = {'critical': 0, 'high': 1, 'medium': 2, 'low': 3}
highest_severity = min(issues, key=lambda x: severity_order.get(x.severity, 99)).severity
report = f"""⚠️ QUALITY CHECK
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Overall Severity: {highest_severity.upper()}
Issues Detected: {len(issues)}
"""
for i, issue in enumerate(issues, 1):
report += f"""Issue {i}: {issue.issue_type.replace('_', ' ').title()}
Severity: {issue.severity}
Description: {issue.description}
Evidence:
"""
for e in issue.evidence[:3]:
report += f" - {e}\n"
report += f"Suggestion: {issue.suggestion}\n\n"
return report
def main():
parser = argparse.ArgumentParser(description='Detect quality issues in conversation')
parser.add_argument('--messages', required=True, help='JSON array of user messages to analyze')
parser.add_argument('--json', action='store_true', help='Output as JSON')
parser.add_argument('--threshold', default='medium',
choices=['low', 'medium', 'high', 'critical'],
help='Minimum severity to report')
args = parser.parse_args()
try:
messages = json.loads(args.messages)
except json.JSONDecodeError:
print("Error: --messages must be a valid JSON array", file=sys.stderr)
sys.exit(1)
issues = detect_quality_issues(messages)
# Filter by threshold
severity_order = {'low': 0, 'medium': 1, 'high': 2, 'critical': 3}
threshold_value = severity_order[args.threshold]
issues = [i for i in issues if severity_order.get(i.severity, 0) >= threshold_value]
if args.json:
output = {
'issues_count': len(issues),
'issues': [asdict(i) for i in issues],
'needs_reanchor': len(issues) > 0
}
print(json.dumps(output, indent=2))
else:
print(format_diagnostic_report(issues))
# Exit code indicates if issues found
sys.exit(0 if not issues else 1)
if __name__ == '__main__':
main()