tractatus/scripts/track-user-suggestions.js
TheFlow 9bc2410420 feat(framework): implement 6 high-priority governance enhancements
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>
2025-10-20 20:41:10 +13:00

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();