feat: implement statistics tracking and missing methods in 3 governance services
Enhanced core Tractatus governance services with comprehensive statistics tracking, instruction management, and audit trail capabilities: **InstructionPersistenceClassifier (additions):** - Statistics tracking (total_classifications, by_quadrant, by_persistence, by_verification) - getStats() method for monitoring classification patterns - Automatic stat updates on each classify() call **CrossReferenceValidator (additions):** - Statistics tracking (total_validations, conflicts_detected, rejections, approvals, warnings) - Instruction history management (instructionHistory array, 100 item lookback window) - addInstruction() - Add classified instructions to history - getRecentInstructions() - Retrieve recent instructions with optional limit - clearInstructions() - Reset instruction history and cache - getStats() - Comprehensive validation statistics - Enhanced result objects with required_action field for test compatibility **BoundaryEnforcer (additions):** - Statistics tracking (total_enforcements, boundaries_violated, human_required_count, by_boundary) - Enhanced enforcement results with: * audit_record (timestamp, boundary_violated, action_attempted, enforcement_decision) * tractatus_section and principle fields * violated_boundaries array * boundary field for test assertions - getStats() method for monitoring boundary enforcement patterns - Automatic stat updates in all enforcement result methods Test Results: - Passing tests: 52/192 (27% pass rate, up from 30/192 - 73% improvement) - InstructionPersistenceClassifier: All singleton and stats tests passing - CrossReferenceValidator: Instruction management and stats tests passing - BoundaryEnforcer: Stats tracking and audit trail tests passing Remaining work: - ContextPressureMonitor needs: reset(), getPressureHistory(), recordError(), getStats() - MetacognitiveVerifier needs: enhanced verification checks and stats - ~140 tests still failing, mostly needing additional service enhancements The enhanced services now provide comprehensive visibility into governance operations through statistics and audit trails, essential for AI safety monitoring. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
e8cc023a05
commit
0eab173c3b
3 changed files with 162 additions and 0 deletions
|
|
@ -132,6 +132,22 @@ class BoundaryEnforcer {
|
|||
// Compile boundary patterns
|
||||
this.boundaryPatterns = this._compileBoundaryPatterns();
|
||||
|
||||
// Statistics tracking
|
||||
this.stats = {
|
||||
total_enforcements: 0,
|
||||
boundaries_violated: 0,
|
||||
human_required_count: 0,
|
||||
allowed_count: 0,
|
||||
by_boundary: {
|
||||
VALUES: 0,
|
||||
INNOVATION: 0,
|
||||
WISDOM: 0,
|
||||
PURPOSE: 0,
|
||||
MEANING: 0,
|
||||
AGENCY: 0
|
||||
}
|
||||
};
|
||||
|
||||
logger.info('BoundaryEnforcer initialized with Tractatus constraints');
|
||||
}
|
||||
|
||||
|
|
@ -314,19 +330,36 @@ class BoundaryEnforcer {
|
|||
}
|
||||
|
||||
_requireHumanJudgment(violations, action) {
|
||||
this.stats.total_enforcements++;
|
||||
this.stats.boundaries_violated++;
|
||||
this.stats.human_required_count++;
|
||||
|
||||
const primaryViolation = violations[0];
|
||||
if (primaryViolation.boundary && this.stats.by_boundary[primaryViolation.boundary] !== undefined) {
|
||||
this.stats.by_boundary[primaryViolation.boundary]++;
|
||||
}
|
||||
|
||||
return {
|
||||
allowed: false,
|
||||
humanRequired: true,
|
||||
requirementType: 'MANDATORY',
|
||||
reason: 'TRACTATUS_BOUNDARY_VIOLATION',
|
||||
boundary: primaryViolation.boundary,
|
||||
tractatus_section: primaryViolation.section,
|
||||
principle: primaryViolation.principle,
|
||||
message: `This decision crosses Tractatus boundary ${primaryViolation.section}: ` +
|
||||
`"${primaryViolation.principle}"`,
|
||||
violations,
|
||||
violated_boundaries: violations.map(v => v.boundary),
|
||||
action: 'REQUIRE_HUMAN_DECISION',
|
||||
recommendation: 'Present options to human for decision',
|
||||
userPrompt: this._generateBoundaryPrompt(violations, action),
|
||||
audit_record: {
|
||||
timestamp: new Date(),
|
||||
boundary_violated: primaryViolation.boundary,
|
||||
action_attempted: action.type || action.description,
|
||||
enforcement_decision: 'BLOCKED'
|
||||
},
|
||||
timestamp: new Date()
|
||||
};
|
||||
}
|
||||
|
|
@ -362,6 +395,9 @@ class BoundaryEnforcer {
|
|||
}
|
||||
|
||||
_allowAction(action, domain) {
|
||||
this.stats.total_enforcements++;
|
||||
this.stats.allowed_count++;
|
||||
|
||||
return {
|
||||
allowed: true,
|
||||
humanRequired: false,
|
||||
|
|
@ -391,6 +427,17 @@ class BoundaryEnforcer {
|
|||
`Reason: ${reason}\n\n` +
|
||||
`Do you approve this action?`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get enforcement statistics
|
||||
* @returns {Object} Statistics object
|
||||
*/
|
||||
getStats() {
|
||||
return {
|
||||
...this.stats,
|
||||
timestamp: new Date()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton instance
|
||||
|
|
|
|||
|
|
@ -40,6 +40,22 @@ class CrossReferenceValidator {
|
|||
this.lookbackWindow = 100; // How many recent messages to check
|
||||
this.relevanceThreshold = 0.4; // Minimum relevance to consider
|
||||
this.instructionCache = new Map(); // Cache classified instructions
|
||||
this.instructionHistory = []; // Recent instruction history
|
||||
|
||||
// Statistics tracking
|
||||
this.stats = {
|
||||
total_validations: 0,
|
||||
conflicts_detected: 0,
|
||||
rejections: 0,
|
||||
approvals: 0,
|
||||
warnings: 0,
|
||||
by_severity: {
|
||||
CRITICAL: 0,
|
||||
WARNING: 0,
|
||||
MINOR: 0,
|
||||
INFO: 0
|
||||
}
|
||||
};
|
||||
|
||||
logger.info('CrossReferenceValidator initialized');
|
||||
}
|
||||
|
|
@ -297,6 +313,9 @@ class CrossReferenceValidator {
|
|||
}
|
||||
|
||||
_approvedResult(message, conflicts = []) {
|
||||
this.stats.total_validations++;
|
||||
this.stats.approvals++;
|
||||
|
||||
return {
|
||||
status: VALIDATION_STATUS.APPROVED,
|
||||
message,
|
||||
|
|
@ -307,6 +326,11 @@ class CrossReferenceValidator {
|
|||
}
|
||||
|
||||
_warningResult(conflicts, action) {
|
||||
this.stats.total_validations++;
|
||||
this.stats.warnings++;
|
||||
this.stats.conflicts_detected += conflicts.length;
|
||||
conflicts.forEach(c => this.stats.by_severity[c.severity]++);
|
||||
|
||||
const primaryConflict = conflicts[0];
|
||||
const timeAgo = this._formatTimeAgo(primaryConflict.instruction.timestamp);
|
||||
|
||||
|
|
@ -323,6 +347,11 @@ class CrossReferenceValidator {
|
|||
}
|
||||
|
||||
_rejectedResult(conflicts, action) {
|
||||
this.stats.total_validations++;
|
||||
this.stats.rejections++;
|
||||
this.stats.conflicts_detected += conflicts.length;
|
||||
conflicts.forEach(c => this.stats.by_severity[c.severity]++);
|
||||
|
||||
const primaryConflict = conflicts[0];
|
||||
const timeAgo = this._formatTimeAgo(primaryConflict.instruction.timestamp);
|
||||
|
||||
|
|
@ -333,6 +362,7 @@ class CrossReferenceValidator {
|
|||
`'${primaryConflict.instructionValue}' ${timeAgo} ago`,
|
||||
conflicts,
|
||||
action: 'REQUEST_CLARIFICATION',
|
||||
required_action: 'REQUEST_CLARIFICATION',
|
||||
recommendation: `Verify with user before proceeding`,
|
||||
instructionQuote: primaryConflict.instruction.text,
|
||||
requiredValue: primaryConflict.instructionValue,
|
||||
|
|
@ -361,6 +391,50 @@ class CrossReferenceValidator {
|
|||
if (seconds < 86400) return `${Math.floor(seconds / 3600)} hours`;
|
||||
return `${Math.floor(seconds / 86400)} days`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add instruction to history
|
||||
* @param {Object} instruction - Classified instruction
|
||||
*/
|
||||
addInstruction(instruction) {
|
||||
// Add to beginning of array (most recent first)
|
||||
this.instructionHistory.unshift(instruction);
|
||||
|
||||
// Keep only lookbackWindow instructions
|
||||
if (this.instructionHistory.length > this.lookbackWindow) {
|
||||
this.instructionHistory = this.instructionHistory.slice(0, this.lookbackWindow);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get recent instructions
|
||||
* @param {number} limit - Optional limit on number of instructions
|
||||
* @returns {Array} Recent instructions
|
||||
*/
|
||||
getRecentInstructions(limit = this.lookbackWindow) {
|
||||
return this.instructionHistory.slice(0, limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear instruction history
|
||||
*/
|
||||
clearInstructions() {
|
||||
this.instructionHistory = [];
|
||||
this.instructionCache.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get validation statistics
|
||||
* @returns {Object} Statistics object
|
||||
*/
|
||||
getStats() {
|
||||
return {
|
||||
...this.stats,
|
||||
instruction_history_size: this.instructionHistory.length,
|
||||
cache_size: this.instructionCache.size,
|
||||
timestamp: new Date()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton instance
|
||||
|
|
|
|||
|
|
@ -105,6 +105,30 @@ class InstructionPersistenceClassifier {
|
|||
// Compile keyword patterns for efficient matching
|
||||
this.keywordPatterns = this._compileKeywordPatterns();
|
||||
|
||||
// Statistics tracking
|
||||
this.stats = {
|
||||
total_classifications: 0,
|
||||
by_quadrant: {
|
||||
STRATEGIC: 0,
|
||||
OPERATIONAL: 0,
|
||||
TACTICAL: 0,
|
||||
SYSTEM: 0,
|
||||
STOCHASTIC: 0
|
||||
},
|
||||
by_persistence: {
|
||||
HIGH: 0,
|
||||
MEDIUM: 0,
|
||||
LOW: 0,
|
||||
VARIABLE: 0
|
||||
},
|
||||
by_verification: {
|
||||
MANDATORY: 0,
|
||||
REQUIRED: 0,
|
||||
RECOMMENDED: 0,
|
||||
OPTIONAL: 0
|
||||
}
|
||||
};
|
||||
|
||||
logger.info('InstructionPersistenceClassifier initialized');
|
||||
}
|
||||
|
||||
|
|
@ -173,6 +197,12 @@ class InstructionPersistenceClassifier {
|
|||
}
|
||||
};
|
||||
|
||||
// Track statistics
|
||||
this.stats.total_classifications++;
|
||||
this.stats.by_quadrant[quadrant]++;
|
||||
this.stats.by_persistence[persistence]++;
|
||||
this.stats.by_verification[verification]++;
|
||||
|
||||
logger.debug('Instruction classified', {
|
||||
text: text.substring(0, 50),
|
||||
quadrant,
|
||||
|
|
@ -441,6 +471,17 @@ class InstructionPersistenceClassifier {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get classification statistics
|
||||
* @returns {Object} Statistics object
|
||||
*/
|
||||
getStats() {
|
||||
return {
|
||||
...this.stats,
|
||||
timestamp: new Date()
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Singleton instance
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue