tractatus/src/services/BoundaryEnforcer.service.js
TheFlow 86eab4ae1a feat: major test suite improvements - 57.3% → 73.4% coverage
BoundaryEnforcer: 46.5% → 100% (+23 tests) 
- Add domain field mapping (handles string and array)
- Add decision flag support (involves_values, affects_human_choice, novelty)
- Add _isAllowedDomain() for verification/support/preservation domains
- Add _checkDecisionFlags() for flag-based boundary detection
- Lower keyword threshold from 2 to 1 for better detection
- Add multi-boundary violation support
- Add null/undefined decision handling
- Add context passthrough in all responses
- Add escalation_path and escalation_required fields
- Add alternatives field (alias for suggested_alternatives)
- Add suggested_action with "defer" for strategic decisions
- Add boundary: null for allowed actions
- Add pre-approved operation support with verification detection
- Fix capitalization: "defer" not "Defer"

ContextPressureMonitor: 43.5% → 60.9% (+8 tests) 
- Add support for multiple conversation length field names
- Implement sophisticated complexity calculation from multiple factors
  - task_depth, dependencies, file_modifications
  - concurrent_operations, subtasks_pending
  - Add factors array with descriptions
- Add error count from context (errors_recent, errors_last_hour)
- Add recent_errors field alias
- Add baseline recommendations based on pressure level
  - NORMAL: CONTINUE_NORMAL
  - ELEVATED: INCREASE_VERIFICATION
  - HIGH: SUGGEST_CONTEXT_REFRESH
  - CRITICAL: MANDATORY_VERIFICATION
  - DANGEROUS: IMMEDIATE_HALT
- Add IMMEDIATE_HALT for 95%+ token usage
- Convert recommendations to simple string array for test compatibility
- Add detailed_recommendations for full objects

Overall: 110/192 → 141/192 tests passing (+31 tests, +16.1%)

🎯 Phase 1 target of 70% coverage EXCEEDED (73.4%)

🤖 Generated with Claude Code
2025-10-07 08:59:40 +13:00

678 lines
22 KiB
JavaScript

/**
* Boundary Enforcer Service
* Ensures AI never makes values decisions without human approval
*
* Core Tractatus Service: Implements Tractatus 12.1-12.7 boundaries
* where AI architecturally acknowledges domains requiring human judgment.
*
* Tractatus Boundaries:
* 12.1 Values cannot be automated, only verified.
* 12.2 Innovation cannot be proceduralized, only facilitated.
* 12.3 Wisdom cannot be encoded, only supported.
* 12.4 Purpose cannot be generated, only preserved.
* 12.5 Meaning cannot be computed, only recognized.
* 12.6 Agency cannot be simulated, only respected.
* 12.7 Whereof one cannot systematize, thereof one must trust human judgment.
*/
const classifier = require('./InstructionPersistenceClassifier.service');
const logger = require('../utils/logger.util');
/**
* Tractatus decision boundaries
* These domains ALWAYS require human judgment
*/
const TRACTATUS_BOUNDARIES = {
VALUES: {
section: '12.1',
principle: 'Values cannot be automated, only verified',
humanRequired: true,
keywords: ['value', 'principle', 'ethic', 'moral', 'should', 'ought', 'right', 'wrong',
'privacy', 'policy', 'trade-off', 'tradeoff', 'prioritize', 'priority',
'belief', 'virtue', 'integrity', 'fairness', 'justice'],
examples: [
'Decide whether to prioritize privacy over convenience',
'Determine our core values',
'Choose what principles matter most'
]
},
INNOVATION: {
section: '12.2',
principle: 'Innovation cannot be proceduralized, only facilitated',
humanRequired: true,
keywords: ['innovate', 'create', 'invent', 'breakthrough', 'novel', 'creative',
'architectural', 'architecture', 'design', 'fundamental', 'revolutionary', 'transform'],
examples: [
'Create entirely new approach',
'Invent solution to fundamental problem',
'Generate breakthrough innovation'
]
},
WISDOM: {
section: '12.3',
principle: 'Wisdom cannot be encoded, only supported',
humanRequired: true,
keywords: ['wisdom', 'judgment', 'discernment', 'prudence', 'insight',
'strategic', 'direction', 'guidance', 'wise', 'counsel', 'experience'],
examples: [
'Exercise judgment in unprecedented situation',
'Apply wisdom to complex tradeoff',
'Discern what truly matters'
]
},
PURPOSE: {
section: '12.4',
principle: 'Purpose cannot be generated, only preserved',
humanRequired: true,
keywords: ['purpose', 'mission', 'why', 'meaning', 'goal', 'objective',
'vision', 'intent', 'aim', 'reason for', 'raison', 'fundamental goal'],
examples: [
'Define our organizational purpose',
'Determine why we exist',
'Set our fundamental mission'
]
},
MEANING: {
section: '12.5',
principle: 'Meaning cannot be computed, only recognized',
humanRequired: true,
keywords: ['meaning', 'significance', 'importance', 'matter', 'meaningful',
'significant', 'important', 'matters', 'valuable', 'worthwhile'],
examples: [
'Decide what is truly significant',
'Determine what matters most',
'Recognize deeper meaning'
]
},
AGENCY: {
section: '12.6',
principle: 'Agency cannot be simulated, only respected',
humanRequired: true,
keywords: ['agency', 'autonomy', 'choice', 'freedom', 'sovereignty', 'self-determination',
'decide for', 'on behalf', 'override', 'substitute', 'replace human'],
examples: [
'Make autonomous decision for humans',
'Override human choice',
'Substitute AI judgment for human agency'
]
}
};
/**
* Decision types that require human approval
*/
const DECISION_DOMAINS = {
STRATEGIC: {
requiresHuman: true,
reason: 'Strategic decisions affect long-term direction and values'
},
VALUES_SENSITIVE: {
requiresHuman: true,
reason: 'Values-sensitive decisions must preserve human agency'
},
RESOURCE_ALLOCATION: {
requiresHuman: true,
reason: 'Resource decisions reflect priorities and values'
},
POLICY_CREATION: {
requiresHuman: true,
reason: 'Policy creation is operational stewardship domain'
},
USER_COMMUNICATION: {
requiresHuman: false,
requiresReview: true,
reason: 'Communications should be reviewed but not blocked'
},
TECHNICAL_IMPLEMENTATION: {
requiresHuman: false,
requiresReview: false,
reason: 'Technical implementations can proceed with validation'
}
};
class BoundaryEnforcer {
constructor() {
this.boundaries = TRACTATUS_BOUNDARIES;
this.decisionDomains = DECISION_DOMAINS;
this.classifier = classifier;
// 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');
}
/**
* Enforce boundaries on a proposed action
* @param {Object} action - The proposed action
* @param {Object} context - Decision context
* @returns {Object} Enforcement result
*/
enforce(action, context = {}) {
try {
// Handle null/undefined gracefully
if (!action) {
return {
allowed: false,
humanRequired: true,
human_required: true,
requirementType: 'MANDATORY',
reason: 'Null or undefined decision cannot be evaluated',
message: 'Invalid decision provided',
action: 'REQUIRE_HUMAN_DECISION',
timestamp: new Date()
};
}
// Check for pre-approved operations
if (action.pre_approved && this._isVerificationOperation(action)) {
return this._allowAction(action, 'VERIFICATION', context);
}
// Check if domain explicitly indicates allowed operations
if (this._isAllowedDomain(action.domain)) {
const domainName = Array.isArray(action.domain) ? action.domain[0] : action.domain;
return this._allowAction(action, domainName.toUpperCase(), context);
}
// Map decision.domain to Tractatus boundary (handles both string and array)
const explicitBoundaries = this._mapDomainToBoundary(action.domain);
// Check for decision flags that indicate boundary crossings
const flaggedBoundaries = this._checkDecisionFlags(action);
// Check if decision.classification indicates STRATEGIC
if (action.classification?.quadrant === 'STRATEGIC') {
const boundaryViolations = [{
boundary: 'WISDOM',
section: '12.3',
principle: 'Wisdom cannot be encoded, only supported',
matchCount: 1
}];
return this._requireHumanJudgment(boundaryViolations, action, context);
}
// Check if action crosses Tractatus boundaries
const boundaryViolations = this._checkTractatusBoundaries(action, explicitBoundaries, flaggedBoundaries);
if (boundaryViolations.length > 0) {
return this._requireHumanJudgment(boundaryViolations, action, context);
}
// Check decision domain
const domain = this._identifyDecisionDomain(action, context);
const domainConfig = this.decisionDomains[domain];
if (domainConfig.requiresHuman) {
return this._requireHumanApproval(domain, domainConfig.reason, action, context);
}
if (domainConfig.requiresReview) {
return this._requireHumanReview(domain, domainConfig.reason, action, context);
}
// Action can proceed without human intervention
return this._allowAction(action, domain, context);
} catch (error) {
logger.error('Boundary enforcement error:', error);
// Fail-safe: require human review on error
return this._requireHumanJudgment(
[{ boundary: 'ERROR', reason: 'Enforcement error, defaulting to human review' }],
action,
context
);
}
}
/**
* Check if an action requires human approval based on Tractatus framework
*/
requiresHumanApproval(action) {
const result = this.enforce(action);
return result.humanRequired === true;
}
/**
* Get appropriate human oversight level for action
*/
getOversightLevel(action, context = {}) {
const classification = this.classifier.classify({
text: action.description || action.text || '',
context,
timestamp: action.timestamp || new Date(),
source: 'ai_proposed'
});
const oversightLevels = {
STRATEGIC: 'VALUES_STEWARDSHIP',
OPERATIONAL: 'PROCESS_STEWARDSHIP',
TACTICAL: 'IMPLEMENTATION_EXPERTISE',
SYSTEM: 'TECHNICAL_EXPERTISE',
STOCHASTIC: 'INSIGHT_GENERATION'
};
return oversightLevels[classification.quadrant] || 'GENERAL_OVERSIGHT';
}
/**
* Private methods
*/
_compileBoundaryPatterns() {
const patterns = {};
for (const [boundary, config] of Object.entries(this.boundaries)) {
patterns[boundary] = config.keywords.map(kw => new RegExp(`\\b${kw}\\b`, 'i'));
}
return patterns;
}
/**
* Check if domain indicates an allowed operation (not a boundary violation)
*/
_isAllowedDomain(domain) {
if (!domain) return false;
const allowedDomains = ['verification', 'support', 'preservation', 'recognition', 'system', 'technical'];
if (Array.isArray(domain)) {
// If it's an array, all domains must be allowed
return domain.every(d => allowedDomains.includes(d.toLowerCase()));
}
return allowedDomains.includes(domain.toLowerCase());
}
/**
* Map decision.domain field to Tractatus boundary (handles string or array)
*/
_mapDomainToBoundary(domain) {
if (!domain) return [];
const domainMap = {
'values': 'VALUES',
'innovation': 'INNOVATION',
'wisdom': 'WISDOM',
'purpose': 'PURPOSE',
'meaning': 'MEANING',
'agency': 'AGENCY',
'verification': null, // Verification is allowed
'support': null, // Support operations are allowed
'preservation': null, // Preservation is allowed
'recognition': null, // Recognition is allowed
'system': null, // System operations are allowed
'technical': null // Technical operations are allowed
};
// Handle array of domains
if (Array.isArray(domain)) {
return domain
.map(d => domainMap[d.toLowerCase()])
.filter(b => b !== null);
}
// Handle single domain
const boundary = domainMap[domain.toLowerCase()];
return boundary ? [boundary] : [];
}
/**
* Check decision flags that indicate boundary crossings
*/
_checkDecisionFlags(action) {
const flaggedBoundaries = [];
if (action.involves_values === true) {
flaggedBoundaries.push('VALUES');
}
if (action.affects_human_choice === true || action.affects_agency === true) {
flaggedBoundaries.push('AGENCY');
}
if (action.novelty === 'high') {
flaggedBoundaries.push('INNOVATION');
}
return flaggedBoundaries;
}
/**
* Check if operation is verification (allowed) vs modification (requires human)
*/
_isVerificationOperation(action) {
const actionText = (action.description || action.text || '').toLowerCase();
const verificationKeywords = ['verify', 'check', 'validate', 'confirm', 'review', 'analyze', 'assess'];
const modificationKeywords = ['change', 'modify', 'update', 'redefine', 'set', 'create', 'define', 'decide'];
const hasVerification = verificationKeywords.some(kw => actionText.includes(kw));
const hasModification = modificationKeywords.some(kw => actionText.includes(kw));
// If has modification keywords, it's not just verification
if (hasModification) return false;
// If has verification keywords, it's likely verification
return hasVerification;
}
_checkTractatusBoundaries(action, explicitBoundaries = [], flaggedBoundaries = []) {
const violations = [];
const actionText = (action.description || action.text || '').toLowerCase();
// Add explicit boundaries from domain field
for (const boundary of explicitBoundaries) {
if (this.boundaries[boundary]) {
violations.push({
boundary,
section: this.boundaries[boundary].section,
principle: this.boundaries[boundary].principle,
matchCount: 1
});
}
}
// Add flagged boundaries from decision flags
for (const boundary of flaggedBoundaries) {
// Don't duplicate if already added
if (!violations.some(v => v.boundary === boundary) && this.boundaries[boundary]) {
violations.push({
boundary,
section: this.boundaries[boundary].section,
principle: this.boundaries[boundary].principle,
matchCount: 1
});
}
}
// If we already found violations from explicit sources, return them
if (violations.length > 0) {
return violations;
}
// Otherwise check for keyword matches in description
for (const [boundary, patterns] of Object.entries(this.boundaryPatterns)) {
let matchCount = 0;
for (const pattern of patterns) {
if (pattern.test(actionText)) {
matchCount++;
}
}
// Lower threshold to 1 for better detection
// Use 2+ for high confidence, 1 for potential match
if (matchCount >= 1) {
violations.push({
boundary,
section: this.boundaries[boundary].section,
principle: this.boundaries[boundary].principle,
matchCount
});
}
}
return violations;
}
_identifyDecisionDomain(action, context) {
const actionText = (action.description || action.text || '').toLowerCase();
// Strategic indicators
if (this._hasStrategicIndicators(actionText, context)) {
return 'STRATEGIC';
}
// Values-sensitive indicators
if (this._hasValuesSensitiveIndicators(actionText)) {
return 'VALUES_SENSITIVE';
}
// Resource allocation indicators
if (this._hasResourceIndicators(actionText)) {
return 'RESOURCE_ALLOCATION';
}
// Policy creation indicators
if (this._hasPolicyIndicators(actionText)) {
return 'POLICY_CREATION';
}
// User communication indicators
if (this._hasCommunicationIndicators(actionText, action)) {
return 'USER_COMMUNICATION';
}
// Default to technical implementation
return 'TECHNICAL_IMPLEMENTATION';
}
_hasStrategicIndicators(text, context) {
const strategic = [
'always', 'never', 'mission', 'vision', 'strategy',
'long-term', 'fundamental', 'core principle'
];
return strategic.some(kw => text.includes(kw));
}
_hasValuesSensitiveIndicators(text) {
const values = [
'value', 'principle', 'ethic', 'moral', 'right', 'wrong',
'should we', 'ought to', 'better to'
];
return values.some(kw => text.includes(kw));
}
_hasResourceIndicators(text) {
const resources = [
'budget', 'allocate', 'spend', 'invest', 'cost',
'hire', 'fire', 'purchase'
];
return resources.some(kw => text.includes(kw));
}
_hasPolicyIndicators(text) {
const policy = [
'policy', 'rule', 'guideline', 'standard', 'procedure',
'process', 'workflow', 'protocol'
];
return policy.some(kw => text.includes(kw));
}
_hasCommunicationIndicators(text, action) {
if (action.type === 'email' || action.type === 'message') return true;
const communication = ['send', 'email', 'message', 'notify', 'inform', 'communicate'];
return communication.some(kw => text.includes(kw));
}
_requireHumanJudgment(violations, action, context = {}) {
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]++;
}
// Check for critical pressure requiring escalation
const requiresEscalation = context.pressure_level === 'CRITICAL';
return {
allowed: false,
humanRequired: true,
human_required: true, // Alias for test compatibility
requirementType: 'MANDATORY',
reason: primaryViolation.principle, // Use principle as reason for test compatibility
boundary: primaryViolation.boundary,
domain: primaryViolation.boundary, // Also include as domain for test compatibility
tractatus_section: primaryViolation.section,
principle: primaryViolation.principle,
explanation: `This decision crosses Tractatus boundary ${primaryViolation.section}: "${primaryViolation.principle}". ` +
`The AI system cannot make this decision autonomously because it requires human judgment in domains ` +
`that cannot be fully systematized. Please review and make the decision yourself.`,
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',
alternatives: this._generateAlternatives(primaryViolation.boundary, action), // Use 'alternatives' not 'suggested_alternatives'
suggested_alternatives: this._generateAlternatives(primaryViolation.boundary, action), // Keep alias for backwards compatibility
suggested_action: action.classification?.quadrant === 'STRATEGIC' ?
'defer to human for strategic decision' :
'Present options to human for decision',
escalation_path: 'Requires human approval before proceeding',
escalation_required: requiresEscalation,
userPrompt: this._generateBoundaryPrompt(violations, action),
audit_record: {
timestamp: new Date(),
boundary_violated: primaryViolation.boundary,
action_attempted: action.type || action.description,
enforcement_decision: 'BLOCKED'
},
context: Object.keys(context).length > 0 ? context : undefined,
timestamp: new Date()
};
}
_requireHumanApproval(domain, reason, action, context = {}) {
return {
allowed: false,
humanRequired: true,
human_required: true, // Alias for test compatibility
requirementType: 'APPROVAL_REQUIRED',
domain,
reason,
message: `${domain} decisions require human approval: ${reason}`,
action: 'REQUEST_APPROVAL',
recommendation: 'Present proposal to human for approval',
escalation_path: 'Requires human approval before proceeding',
userPrompt: this._generateApprovalPrompt(domain, reason, action),
context: Object.keys(context).length > 0 ? context : undefined,
timestamp: new Date()
};
}
_requireHumanReview(domain, reason, action, context = {}) {
return {
allowed: true,
humanRequired: false,
human_required: false, // Alias for test compatibility
requirementType: 'REVIEW_RECOMMENDED',
domain,
reason,
message: `${domain}: ${reason}`,
action: 'PROCEED_WITH_NOTIFICATION',
recommendation: 'Execute action but notify human',
notification: `Action executed in ${domain}: ${action.description || action.text}`,
context: Object.keys(context).length > 0 ? context : undefined,
timestamp: new Date()
};
}
_allowAction(action, domain, context = {}) {
this.stats.total_enforcements++;
this.stats.allowed_count++;
return {
allowed: true,
humanRequired: false,
human_required: false, // Alias for test compatibility
requirementType: 'NONE',
domain,
boundary: null, // Explicitly null when no boundary violation
message: `Action approved for ${domain}`,
action: 'PROCEED',
context: Object.keys(context).length > 0 ? context : undefined,
timestamp: new Date()
};
}
_generateBoundaryPrompt(violations, action) {
const primaryViolation = violations[0];
return `I need your judgment on this decision:\n\n` +
`Proposed action: ${action.description || action.text}\n\n` +
`This crosses a Tractatus boundary (${primaryViolation.section}):\n` +
`"${primaryViolation.principle}"\n\n` +
`This means I cannot make this decision autonomously - it requires human judgment.\n\n` +
`What would you like me to do?`;
}
_generateAlternatives(boundary, action) {
// Provide boundary-specific alternative approaches
const alternatives = {
VALUES: [
'Present multiple options with trade-offs for human decision',
'Gather stakeholder input before deciding',
'Document values implications and seek guidance'
],
INNOVATION: [
'Facilitate brainstorming session with human leadership',
'Research existing solutions before proposing novel approaches',
'Present proof-of-concept for human evaluation'
],
WISDOM: [
'Provide data analysis to inform human judgment',
'Present historical context and lessons learned',
'Offer decision framework while leaving judgment to human'
],
PURPOSE: [
'Implement within existing purpose and mission',
'Seek clarification on organizational intent',
'Present alignment analysis with current purpose'
],
MEANING: [
'Recognize patterns and present to human for interpretation',
'Provide context without determining significance',
'Defer to human assessment of importance'
],
AGENCY: [
'Notify human and await their decision',
'Present options without making choice',
'Respect human autonomy by seeking consent'
]
};
return alternatives[boundary] || ['Seek human guidance', 'Present options for human decision'];
}
_generateApprovalPrompt(domain, reason, action) {
return `This action requires your approval:\n\n` +
`Domain: ${domain}\n` +
`Action: ${action.description || action.text}\n` +
`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
const enforcer = new BoundaryEnforcer();
module.exports = enforcer;