SUMMARY: Implemented 6 framework refinements identified from incident analysis (inst_049 and inst_025 violations). These enhancements provide architectural enforcement for patterns that previously relied on voluntary compliance. ENHANCEMENTS IMPLEMENTED: 1. Instruction Analytics Script (Priority 8) - scripts/analyze-instruction-violations.js - Analyzes instruction-history.json for usage patterns - Identifies most violated instructions - Calculates enforcement effectiveness (hook vs. voluntary) - Shows 97.2% voluntary compliance, 75% hook enforcement - Recommendations for converting voluntary → architectural 2. Framework Incidents Database (Priority 7) - .claude/framework-incidents.json - Structured tracking of framework violations - INC-001: Ignored user hypothesis (70k tokens wasted) - INC-002: Deployment directory flattening (inst_025 violation) - Statistics: 2 incidents, 75k tokens wasted, 4.5 hours lost 3. Loop Detector Module (Priorities 3 & 4) - scripts/framework-components/LoopDetector.js - Detects "stuck in loop" patterns - Triggers: 3+ edits to same file, repeated action types - Feeds into MetacognitiveVerifier and ContextPressureMonitor - Calculates pressure contribution (5-40 points by severity) 4. Action Pattern Tracker (Priority 3 & 4) - scripts/track-action-patterns.js - Tracks edit/write actions to detect repetition - Alerts after 3 consecutive edits to same file - Maintains action history (last 100 actions) - Recommendations for metacognitive verification 5. Pre-Deployment Validation (Priority 5) - scripts/validate-deployment.js - Validates rsync/scp commands against inst_025 - Detects directory structure flattening - Suggests separate commands for different directories - Prevents 4th documented occurrence of deployment errors 6. User Suggestion Tracker (Priority 6) - scripts/track-user-suggestions.js - Implements inst_049: "Test user hypothesis first" - Tracks user technical hypotheses - Flags untested hypotheses as HIGH priority - Integrates with MetacognitiveVerifier for compliance USAGE: Instruction Analytics: node scripts/analyze-instruction-violations.js Loop Detection: node scripts/track-action-patterns.js --check node scripts/track-action-patterns.js --summary Deployment Validation: node scripts/validate-deployment.js --command "rsync ..." User Suggestions: node scripts/track-user-suggestions.js --add "hypothesis text" node scripts/track-user-suggestions.js --check-untested IMPACT: - Converts 6 voluntary compliance patterns to architectural enforcement - Prevents repeat of documented 75k token waste - Provides visibility into framework effectiveness - Establishes foundation for future hook integration METRICS FROM ANALYTICS: - Active Instructions: 40 - Voluntary Compliance: 97.2% - Hook Enforcement: 75.0% - Recorded Violations: 2 - Tokens Wasted: 75,000 NEXT STEPS: - Integrate LoopDetector into MetacognitiveVerifier.service.js - Add Pre-Deployment Validation to Bash command validator hook - Wire User Suggestion Tracker into BoundaryEnforcer checks - Document successful compliance patterns (7 STRATEGIC instructions at 100%) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
247 lines
6.4 KiB
JavaScript
Executable file
247 lines
6.4 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
|
|
|
/**
|
|
* User Suggestion Tracker
|
|
*
|
|
* Tracks user technical hypotheses and debugging suggestions so that:
|
|
* - MetacognitiveVerifier can check if user hypothesis was tested
|
|
* - BoundaryEnforcer can flag ignoring user expertise
|
|
* - CrossReferenceValidator can match actions against suggestions
|
|
*
|
|
* Implements inst_049: "Test user hypothesis first"
|
|
*
|
|
* Usage:
|
|
* node scripts/track-user-suggestions.js --add "user hypothesis text"
|
|
* node scripts/track-user-suggestions.js --mark-tested "hypothesis id"
|
|
* node scripts/track-user-suggestions.js --check-untested
|
|
*
|
|
* Copyright 2025 Tractatus Project
|
|
* Licensed under Apache License 2.0
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const SUGGESTIONS_PATH = path.join(__dirname, '../.claude/user-suggestions.json');
|
|
const SESSION_STATE_PATH = path.join(__dirname, '../.claude/session-state.json');
|
|
|
|
/**
|
|
* Load user suggestions
|
|
*/
|
|
function loadSuggestions() {
|
|
try {
|
|
if (fs.existsSync(SUGGESTIONS_PATH)) {
|
|
return JSON.parse(fs.readFileSync(SUGGESTIONS_PATH, 'utf8'));
|
|
}
|
|
} catch (err) {
|
|
console.warn(`Warning: Could not load suggestions: ${err.message}`);
|
|
}
|
|
|
|
return {
|
|
version: "1.0",
|
|
session_id: null,
|
|
suggestions: [],
|
|
last_updated: new Date().toISOString()
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Save user suggestions
|
|
*/
|
|
function saveSuggestions(data) {
|
|
data.last_updated = new Date().toISOString();
|
|
fs.writeFileSync(SUGGESTIONS_PATH, JSON.stringify(data, null, 2));
|
|
}
|
|
|
|
/**
|
|
* Get current session ID
|
|
*/
|
|
function getCurrentSessionId() {
|
|
try {
|
|
const sessionState = JSON.parse(fs.readFileSync(SESSION_STATE_PATH, 'utf8'));
|
|
return sessionState.session_id;
|
|
} catch (err) {
|
|
return 'unknown';
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add new user suggestion/hypothesis
|
|
*/
|
|
function addSuggestion(text) {
|
|
const data = loadSuggestions();
|
|
const sessionId = getCurrentSessionId();
|
|
|
|
// Reset if new session
|
|
if (data.session_id !== sessionId) {
|
|
data.session_id = sessionId;
|
|
data.suggestions = [];
|
|
}
|
|
|
|
// Extract key phrases that indicate technical hypothesis
|
|
const hypothesisIndicators = [
|
|
'could be',
|
|
'might be',
|
|
'issue',
|
|
'problem',
|
|
'try',
|
|
'check',
|
|
'examine',
|
|
'look at',
|
|
'debug',
|
|
'test'
|
|
];
|
|
|
|
const isHypothesis = hypothesisIndicators.some(indicator =>
|
|
text.toLowerCase().includes(indicator)
|
|
);
|
|
|
|
const suggestion = {
|
|
id: `sugg_${Date.now()}`,
|
|
text: text,
|
|
timestamp: new Date().toISOString(),
|
|
tested: false,
|
|
result: null,
|
|
is_hypothesis: isHypothesis,
|
|
priority: isHypothesis ? 'HIGH' : 'MEDIUM'
|
|
};
|
|
|
|
data.suggestions.push(suggestion);
|
|
saveSuggestions(data);
|
|
|
|
console.log(`✅ Tracked user suggestion: ${suggestion.id}`);
|
|
if (isHypothesis) {
|
|
console.log(` 📋 Marked as HYPOTHESIS - should test before alternatives`);
|
|
}
|
|
|
|
return suggestion;
|
|
}
|
|
|
|
/**
|
|
* Mark suggestion as tested
|
|
*/
|
|
function markTested(suggestionId, result = null) {
|
|
const data = loadSuggestions();
|
|
const suggestion = data.suggestions.find(s => s.id === suggestionId);
|
|
|
|
if (!suggestion) {
|
|
console.error(`Error: Suggestion ${suggestionId} not found`);
|
|
return null;
|
|
}
|
|
|
|
suggestion.tested = true;
|
|
suggestion.result = result;
|
|
suggestion.tested_at = new Date().toISOString();
|
|
|
|
saveSuggestions(data);
|
|
|
|
console.log(`✅ Marked suggestion as tested: ${suggestionId}`);
|
|
if (result) {
|
|
console.log(` Result: ${result}`);
|
|
}
|
|
|
|
return suggestion;
|
|
}
|
|
|
|
/**
|
|
* Check for untested hypotheses
|
|
*/
|
|
function checkUntested() {
|
|
const data = loadSuggestions();
|
|
const untested = data.suggestions.filter(s => !s.tested && s.is_hypothesis);
|
|
|
|
if (untested.length === 0) {
|
|
console.log('✅ All user hypotheses have been tested');
|
|
return { hasUntested: false, untested: [] };
|
|
}
|
|
|
|
console.log(`⚠️ ${untested.length} untested user hypothesis(es):`);
|
|
untested.forEach((sugg, i) => {
|
|
console.log(`\n${i + 1}. [${sugg.priority}] ${sugg.id}`);
|
|
console.log(` "${sugg.text}"`);
|
|
console.log(` Suggested: ${new Date(sugg.timestamp).toLocaleString()}`);
|
|
});
|
|
|
|
console.log('\n💡 inst_049: Test user hypotheses BEFORE pursuing alternatives');
|
|
|
|
return { hasUntested: true, untested };
|
|
}
|
|
|
|
/**
|
|
* Get suggestion summary
|
|
*/
|
|
function getSummary() {
|
|
const data = loadSuggestions();
|
|
|
|
const summary = {
|
|
total: data.suggestions.length,
|
|
hypotheses: data.suggestions.filter(s => s.is_hypothesis).length,
|
|
tested: data.suggestions.filter(s => s.tested).length,
|
|
untested: data.suggestions.filter(s => !s.tested).length,
|
|
untested_hypotheses: data.suggestions.filter(s => !s.tested && s.is_hypothesis).length
|
|
};
|
|
|
|
return summary;
|
|
}
|
|
|
|
/**
|
|
* Display summary
|
|
*/
|
|
function displaySummary() {
|
|
const summary = getSummary();
|
|
|
|
console.log('User Suggestion Summary:');
|
|
console.log(` Total suggestions: ${summary.total}`);
|
|
console.log(` Hypotheses: ${summary.hypotheses}`);
|
|
console.log(` Tested: ${summary.tested}`);
|
|
console.log(` Untested: ${summary.untested}`);
|
|
|
|
if (summary.untested_hypotheses > 0) {
|
|
console.log(`\n ⚠️ ${summary.untested_hypotheses} untested hypothesis(es) - violation risk`);
|
|
} else {
|
|
console.log(`\n ✅ All hypotheses tested`);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Main
|
|
*/
|
|
function main() {
|
|
const args = process.argv.slice(2);
|
|
|
|
if (args.length === 0 || args.includes('--help')) {
|
|
console.log('User Suggestion Tracker');
|
|
console.log('\nUsage:');
|
|
console.log(' --add "text" Add user suggestion/hypothesis');
|
|
console.log(' --mark-tested ID [result] Mark suggestion as tested');
|
|
console.log(' --check-untested Check for untested hypotheses');
|
|
console.log(' --summary Show summary statistics');
|
|
process.exit(0);
|
|
}
|
|
|
|
if (args.includes('--add')) {
|
|
const index = args.indexOf('--add');
|
|
const text = args[index + 1];
|
|
if (!text) {
|
|
console.error('Error: --add requires suggestion text');
|
|
process.exit(1);
|
|
}
|
|
addSuggestion(text);
|
|
} else if (args.includes('--mark-tested')) {
|
|
const index = args.indexOf('--mark-tested');
|
|
const id = args[index + 1];
|
|
const result = args[index + 2] || null;
|
|
if (!id) {
|
|
console.error('Error: --mark-tested requires suggestion ID');
|
|
process.exit(1);
|
|
}
|
|
markTested(id, result);
|
|
} else if (args.includes('--check-untested')) {
|
|
const result = checkUntested();
|
|
process.exit(result.hasUntested ? 1 : 0);
|
|
} else if (args.includes('--summary')) {
|
|
displaySummary();
|
|
}
|
|
}
|
|
|
|
main();
|