Completes enforcement implementation from ENFORCEMENT_AUDIT.md analysis: ✅ Implemented (6 enforcement mechanisms): 1. Token checkpoint monitoring (inst_075) - .claude/hooks/check-token-checkpoint.js - PostToolUse hook integration 2. Trigger word detection (inst_078, inst_082) - .claude/hooks/trigger-word-checker.js (already completed) - "ff" and "ffs" triggers architecturally enforced 3. Framework activity verification (inst_064) - Enhanced scripts/session-init.js with fade detection - Alerts when components stale >20 messages 4. Test requirement enforcement (inst_068) - Enhanced .git/hooks/pre-commit - Runs tests if test files exist for modified code - Blocks commits on test failures 5. Background process tracking (inst_023) - scripts/track-background-process.js - Integrated into session-init.js and session-closedown.js - Tracks persistent vs temporary processes 6. Security logging verification (inst_046) - scripts/verify-security-logging.js - Can be integrated into deployment workflow 7. Meta-enforcement monitoring system - scripts/audit-enforcement.js - Scans HIGH persistence instructions for imperatives - Reports enforcement gaps (currently 28/39 gaps) 🔒 Protection Added: - inst_027: Hard block on instruction-history.json edits - Conventional commit format enforcement (inst_066) - CSP + test validation in pre-commit hook 📊 Current Enforcement Status: - Baseline: 11/39 imperative instructions enforced (28%) - Framework fade detection operational - Token checkpoints architecturally monitored 🎯 Philosophy: "If it's MANDATORY, it must be ENFORCED architecturally, not documented." This addresses the root cause of voluntary compliance failures identified when Claude missed "ffs" trigger and token checkpoints despite active HIGH persistence instructions. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
97 lines
2.4 KiB
JavaScript
Executable file
97 lines
2.4 KiB
JavaScript
Executable file
#!/usr/bin/env node
|
|
/**
|
|
* Background Process Tracker - Enforces inst_023
|
|
*/
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const SESSION_STATE = path.join(__dirname, '../.claude/session-state.json');
|
|
|
|
function loadState() {
|
|
if (!fs.existsSync(SESSION_STATE)) return { background_processes: [] };
|
|
return JSON.parse(fs.readFileSync(SESSION_STATE, 'utf8'));
|
|
}
|
|
|
|
function saveState(state) {
|
|
fs.writeFileSync(SESSION_STATE, JSON.stringify(state, null, 2));
|
|
}
|
|
|
|
function isRunning(pid) {
|
|
try {
|
|
process.kill(pid, 0);
|
|
return true;
|
|
} catch (e) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
function register(pid, description, persistent = false) {
|
|
const state = loadState();
|
|
if (!state.background_processes) state.background_processes = [];
|
|
|
|
state.background_processes.push({
|
|
pid: parseInt(pid),
|
|
description,
|
|
persistent,
|
|
started_at: new Date().toISOString(),
|
|
session: state.session_id
|
|
});
|
|
|
|
saveState(state);
|
|
console.log(`✅ Registered: PID ${pid} - ${description}${persistent ? ' [PERSISTENT]' : ''}`);
|
|
}
|
|
|
|
function list() {
|
|
const state = loadState();
|
|
const procs = state.background_processes || [];
|
|
|
|
if (procs.length === 0) {
|
|
console.log('No tracked processes');
|
|
return;
|
|
}
|
|
|
|
console.log('\n📋 Background Processes:\n');
|
|
procs.forEach(p => {
|
|
const status = isRunning(p.pid) ? '✓' : '✗';
|
|
console.log(`${status} PID ${p.pid}: ${p.description} ${p.persistent ? '[PERSISTENT]' : ''}`);
|
|
});
|
|
console.log('');
|
|
}
|
|
|
|
function cleanup(force = false) {
|
|
const state = loadState();
|
|
const procs = state.background_processes || [];
|
|
let killed = 0;
|
|
const remaining = [];
|
|
|
|
procs.forEach(p => {
|
|
if (!isRunning(p.pid)) return;
|
|
if (p.persistent && !force) {
|
|
remaining.push(p);
|
|
return;
|
|
}
|
|
try {
|
|
process.kill(p.pid, 'SIGTERM');
|
|
console.log(`✓ Killed PID ${p.pid}`);
|
|
killed++;
|
|
} catch (err) {
|
|
remaining.push(p);
|
|
}
|
|
});
|
|
|
|
state.background_processes = remaining;
|
|
saveState(state);
|
|
console.log(`\n✅ Cleanup: ${killed} killed, ${remaining.length} remaining\n`);
|
|
}
|
|
|
|
const cmd = process.argv[2];
|
|
if (cmd === 'register') {
|
|
register(process.argv[3], process.argv[4], process.argv.includes('--persistent'));
|
|
} else if (cmd === 'list') {
|
|
list();
|
|
} else if (cmd === 'cleanup') {
|
|
cleanup(process.argv.includes('--force'));
|
|
} else {
|
|
console.log('Usage: register <pid> <desc> [--persistent] | list | cleanup [--force]');
|
|
}
|