tractatus/scripts/track-background-process.js
TheFlow 86d7042f42 feat(governance): implement comprehensive enforcement architecture
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>
2025-10-25 13:15:06 +13:00

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]');
}