/**
 * Gate Validators for 4-Layer Operation Verification System
 *
 * Individual validator functions for each gate layer:
 * - Layer 1: Schema validation (JSON Schema, format constraints)
 * - Layer 2: Semantic validation (business rules, anti-hallucination)
 * - Layer 3: Referential validation (cross-entity integrity)
 * - Layer 4: Protocol validation (RCASD-IVTR+C lifecycle)
 *
 * Moved to core for proper layering (formerly in dispatch).
 *
 * @task T2936
 * @task T3138
 * @task T5707
 * @epic T2908
 */
import { ADR_STATUSES, LIFECYCLE_STAGE_STATUSES, MANIFEST_STATUSES, SESSION_STATUSES, TASK_STATUSES, } from '@cleocode/contracts';
import { ErrorSeverity } from '../compliance/protocol-types.js';
import { GateLayer, GateStatus, isValidWorkflowGateName, WORKFLOW_GATE_SEQUENCE, } from './operation-verification-gates.js';
/**
 * Layer 1: Schema Validation
 *
 * Validates operation parameters against JSON Schema definitions.
 * Checks required fields, data types, and format constraints.
 */
export async function validateLayer1Schema(context) {
    const violations = [];
    // Task ID validation (if present)
    if (context.params?.taskId) {
        const taskId = context.params.taskId;
        if (!taskId.match(/^T[0-9]+$/)) {
            violations.push({
                layer: GateLayer.SCHEMA,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_TASK_ID',
                message: `Invalid task ID format: ${taskId}`,
                field: 'taskId',
                value: taskId,
                constraint: 'Must match pattern ^T[0-9]+$',
                fix: 'Use format T followed by digits (e.g., T1234)',
            });
        }
    }
    // Title validation (for create/update operations)
    if (context.params?.title !== undefined) {
        const title = context.params.title;
        if (typeof title !== 'string' || title.length < 5 || title.length > 100) {
            violations.push({
                layer: GateLayer.SCHEMA,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_TITLE',
                message: 'Title must be 5-100 characters',
                field: 'title',
                value: title,
                constraint: 'length: 5-100',
                fix: 'Provide a title between 5 and 100 characters',
            });
        }
    }
    // Description validation (Section 8.1: 10-1000 characters)
    if (context.params?.description !== undefined) {
        const description = context.params.description;
        if (typeof description !== 'string' || description.length < 10 || description.length > 1000) {
            violations.push({
                layer: GateLayer.SCHEMA,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_DESCRIPTION',
                message: 'Description must be 10-1000 characters',
                field: 'description',
                value: typeof description === 'string' ? `${description.substring(0, 50)}...` : description,
                constraint: 'length: 10-1000',
                fix: 'Provide a description between 10 and 1000 characters',
            });
        }
    }
    // Manifest ID format validation (Section 8.2: ^T\d{3,}-[a-z0-9-]+$)
    if (context.params?.manifestEntry) {
        const entry = context.params.manifestEntry;
        if (entry.id) {
            const manifestId = entry.id;
            if (!manifestId.match(/^T\d{3,}-[a-z0-9-]+$/)) {
                violations.push({
                    layer: GateLayer.SCHEMA,
                    severity: ErrorSeverity.ERROR,
                    code: 'E_INVALID_MANIFEST_ID',
                    message: `Invalid manifest ID format: ${manifestId}`,
                    field: 'manifestEntry.id',
                    value: manifestId,
                    constraint: 'Must match ^T\\d{3,}-[a-z0-9-]+$',
                    fix: 'Use format T####-slug (e.g., T1234-research-output)',
                });
            }
        }
        // Date format validation (Section 8.2: ISO 8601 YYYY-MM-DD)
        if (entry.date) {
            const date = entry.date;
            if (!date.match(/^\d{4}-\d{2}-\d{2}$/)) {
                violations.push({
                    layer: GateLayer.SCHEMA,
                    severity: ErrorSeverity.ERROR,
                    code: 'E_INVALID_DATE_FORMAT',
                    message: `Invalid date format: ${date}`,
                    field: 'manifestEntry.date',
                    value: date,
                    constraint: 'Must be ISO 8601 YYYY-MM-DD',
                    fix: 'Use date format YYYY-MM-DD (e.g., 2026-02-06)',
                });
            }
        }
        // Agent type validation (Section 8.2: known protocol type)
        if (entry.agent_type) {
            const agentType = entry.agent_type;
            const validAgentTypes = [
                'research',
                'analysis',
                'specification',
                'implementation',
                'testing',
                'validation',
                'documentation',
                'release',
            ];
            if (!validAgentTypes.includes(agentType)) {
                violations.push({
                    layer: GateLayer.SCHEMA,
                    severity: ErrorSeverity.ERROR,
                    code: 'E_INVALID_AGENT_TYPE',
                    message: `Invalid agent type: ${agentType}`,
                    field: 'manifestEntry.agent_type',
                    value: agentType,
                    constraint: `Must be one of: ${validAgentTypes.join(', ')}`,
                    fix: `Use one of: ${validAgentTypes.join(', ')}`,
                });
            }
        }
    }
    // Status validation — domain-aware
    if (context.params?.status) {
        const status = context.params.status;
        const validStatuses = (() => {
            if (context.domain === 'pipeline' && context.operation === 'stage.record') {
                return LIFECYCLE_STAGE_STATUSES;
            }
            if (context.domain === 'admin' && context.operation?.startsWith('adr.')) {
                return ADR_STATUSES;
            }
            if (context.domain === 'session') {
                return SESSION_STATUSES;
            }
            if (context.domain === 'pipeline' && context.operation?.startsWith('manifest.')) {
                return MANIFEST_STATUSES;
            }
            return TASK_STATUSES;
        })();
        if (!validStatuses.includes(status)) {
            violations.push({
                layer: GateLayer.SCHEMA,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_STATUS',
                message: `Invalid status: ${status}`,
                field: 'status',
                value: status,
                constraint: `Must be one of: ${validStatuses.join(', ')}`,
                fix: `Use one of: ${validStatuses.join(', ')}`,
            });
        }
    }
    // Priority validation - accepts both string names and numeric 1-9
    if (context.params?.priority !== undefined) {
        const priority = context.params.priority;
        const validStringPriorities = ['critical', 'high', 'medium', 'low'];
        let isValid = false;
        if (typeof priority === 'string') {
            if (validStringPriorities.includes(priority.toLowerCase())) {
                isValid = true;
            }
            const asNum = Number(priority);
            if (!Number.isNaN(asNum) && Number.isInteger(asNum) && asNum >= 1 && asNum <= 9) {
                isValid = true;
            }
        }
        else if (typeof priority === 'number') {
            if (Number.isInteger(priority) && priority >= 1 && priority <= 9) {
                isValid = true;
            }
        }
        if (!isValid) {
            violations.push({
                layer: GateLayer.SCHEMA,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_PRIORITY',
                message: `Invalid priority: ${priority}. Must be critical|high|medium|low or numeric 1-9`,
                field: 'priority',
                value: priority,
                constraint: 'critical|high|medium|low or 1-9',
                fix: 'Set priority to critical, high, medium, low, or a number 1-9',
            });
        }
    }
    return {
        layer: GateLayer.SCHEMA,
        status: violations.length > 0 ? GateStatus.FAILED : GateStatus.PASSED,
        passed: violations.length === 0,
        violations,
        duration_ms: 0,
    };
}
/**
 * Layer 2: Semantic Validation
 *
 * Validates business rules and logical constraints.
 */
export async function validateLayer2Semantic(context) {
    const violations = [];
    // Title and description must be different (anti-hallucination)
    if (context.params?.title && context.params?.description) {
        const title = context.params.title;
        const description = context.params.description;
        if (title === description) {
            violations.push({
                layer: GateLayer.SEMANTIC,
                severity: ErrorSeverity.ERROR,
                code: 'E_TITLE_DESCRIPTION_SAME',
                message: 'Title and description must be different',
                field: 'description',
                constraint: 'must differ from title',
                fix: 'Provide a unique description that explains the task',
            });
        }
    }
    // No future timestamps
    if (context.params?.created || context.params?.updated) {
        const now = new Date();
        for (const field of ['created', 'updated']) {
            const value = context.params?.[field];
            if (value) {
                const timestamp = new Date(value);
                if (!Number.isNaN(timestamp.getTime()) && timestamp > now) {
                    violations.push({
                        layer: GateLayer.SEMANTIC,
                        severity: ErrorSeverity.ERROR,
                        code: 'E_FUTURE_TIMESTAMP',
                        message: `Timestamp ${field} cannot be in the future: ${value}`,
                        field,
                        value,
                        constraint: `${field} <= current time`,
                        fix: `Set ${field} to current or past timestamp`,
                    });
                }
            }
        }
    }
    // Manifest date must not be future
    if (context.params?.manifestEntry) {
        const entry = context.params.manifestEntry;
        if (entry.date) {
            const dateStr = entry.date;
            const today = new Date().toISOString().split('T')[0];
            if (dateStr > today) {
                violations.push({
                    layer: GateLayer.SEMANTIC,
                    severity: ErrorSeverity.ERROR,
                    code: 'E_FUTURE_TIMESTAMP',
                    message: `Manifest date cannot be in the future: ${dateStr}`,
                    field: 'manifestEntry.date',
                    value: dateStr,
                    constraint: 'date <= today',
                    fix: 'Set date to today or earlier',
                });
            }
        }
    }
    // Circular dependency check
    if (context.params?.depends) {
        const depends = context.params.depends;
        const taskId = context.params?.taskId;
        if (taskId && depends.includes(taskId)) {
            violations.push({
                layer: GateLayer.SEMANTIC,
                severity: ErrorSeverity.ERROR,
                code: 'E_CIRCULAR_DEPENDENCY',
                message: 'Task cannot depend on itself',
                field: 'depends',
                constraint: 'no self-reference',
                fix: 'Remove self-reference from dependencies',
            });
        }
    }
    // Session scope validation
    if (context.domain === 'session' && context.operation === 'start') {
        const scope = context.params?.scope;
        if (scope && scope !== 'global' && !scope.match(/^(epic|task):/)) {
            violations.push({
                layer: GateLayer.SEMANTIC,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_SCOPE',
                message: `Invalid session scope format: ${scope}`,
                field: 'scope',
                constraint: 'Must be epic:<id>, task:<id>, or global',
                fix: 'Provide scope as "global" or "epic:TXXX"',
            });
        }
    }
    // Notes required for completion
    if (context.operation === 'complete' && context.params?.notes === undefined) {
        violations.push({
            layer: GateLayer.SEMANTIC,
            severity: ErrorSeverity.WARNING,
            code: 'E_NOTES_RECOMMENDED',
            message: 'Completion notes are recommended',
            field: 'notes',
            constraint: 'should be present',
            fix: 'Add --notes "..." to document completion',
        });
    }
    return {
        layer: GateLayer.SEMANTIC,
        status: violations.filter((v) => v.severity === ErrorSeverity.ERROR).length > 0
            ? GateStatus.FAILED
            : GateStatus.PASSED,
        passed: violations.filter((v) => v.severity === ErrorSeverity.ERROR).length === 0,
        violations,
        duration_ms: 0,
    };
}
/**
 * Layer 3: Referential Validation
 *
 * Validates cross-entity references and relationships.
 */
export async function validateLayer3Referential(context) {
    const violations = [];
    // Parent task validation
    if (context.params?.parent) {
        const parent = context.params.parent;
        if (!parent.match(/^T[0-9]+$/)) {
            violations.push({
                layer: GateLayer.REFERENTIAL,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_PARENT_REF',
                message: `Invalid parent reference: ${parent}`,
                field: 'parent',
                value: parent,
                constraint: 'Must be valid task ID',
                fix: 'Verify parent task exists with: cleo exists <id>',
            });
        }
    }
    // Dependency validation
    if (context.params?.depends) {
        const depends = context.params.depends;
        for (const depId of depends) {
            if (!depId.match(/^T[0-9]+$/)) {
                violations.push({
                    layer: GateLayer.REFERENTIAL,
                    severity: ErrorSeverity.ERROR,
                    code: 'E_INVALID_DEPENDENCY_REF',
                    message: `Invalid dependency reference: ${depId}`,
                    field: 'depends',
                    value: depId,
                    constraint: 'Must be valid task ID',
                    fix: 'Verify dependency exists with: cleo find --id <id>',
                });
            }
        }
    }
    // Task existence validation
    if (['update', 'complete', 'delete', 'archive'].includes(context.operation)) {
        const taskId = context.params?.taskId;
        if (!taskId) {
            violations.push({
                layer: GateLayer.REFERENTIAL,
                severity: ErrorSeverity.ERROR,
                code: 'E_TASK_ID_REQUIRED',
                message: 'Task ID is required for this operation',
                field: 'taskId',
                constraint: 'required',
                fix: 'Provide task ID with --taskId T####',
            });
        }
    }
    // Task start validation
    if (context.domain === 'tasks' && context.operation === 'start') {
        const taskId = context.params?.taskId;
        if (taskId && !taskId.match(/^T[0-9]+$/)) {
            violations.push({
                layer: GateLayer.REFERENTIAL,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_TASK_REF',
                message: `Invalid task reference: ${taskId}`,
                field: 'taskId',
                value: taskId,
                constraint: 'Must be valid task ID',
                fix: 'Use valid task ID format: T####',
            });
        }
    }
    // Hierarchy depth validation
    if (context.params?.depth !== undefined) {
        const depth = context.params.depth;
        if (typeof depth === 'number' && depth > GATE_VALIDATION_RULES.MAX_DEPTH) {
            violations.push({
                layer: GateLayer.REFERENTIAL,
                severity: ErrorSeverity.ERROR,
                code: 'E_DEPTH_EXCEEDED',
                message: `Hierarchy depth ${depth} exceeds maximum of ${GATE_VALIDATION_RULES.MAX_DEPTH}`,
                field: 'depth',
                value: depth,
                constraint: `max depth: ${GATE_VALIDATION_RULES.MAX_DEPTH}`,
                fix: 'Flatten hierarchy to max 3 levels (epic -> task -> subtask)',
            });
        }
    }
    // Sibling limit validation
    if (context.params?.siblingCount !== undefined) {
        const siblingCount = context.params.siblingCount;
        if (typeof siblingCount === 'number' &&
            GATE_VALIDATION_RULES.MAX_SIBLINGS > 0 &&
            siblingCount >= GATE_VALIDATION_RULES.MAX_SIBLINGS) {
            violations.push({
                layer: GateLayer.REFERENTIAL,
                severity: ErrorSeverity.ERROR,
                code: 'E_SIBLING_LIMIT',
                message: `Parent already has ${siblingCount} children (max ${GATE_VALIDATION_RULES.MAX_SIBLINGS})`,
                field: 'siblingCount',
                value: siblingCount,
                constraint: `max siblings: ${GATE_VALIDATION_RULES.MAX_SIBLINGS}`,
                fix: 'Create a new parent to group related tasks',
            });
        }
    }
    // Manifest file reference validation
    if (context.params?.manifestEntry) {
        const entry = context.params.manifestEntry;
        if (typeof entry.file === 'string' && entry.file.length === 0) {
            violations.push({
                layer: GateLayer.REFERENTIAL,
                severity: ErrorSeverity.ERROR,
                code: 'E_EMPTY_FILE_REF',
                message: 'Manifest entry file reference cannot be empty',
                field: 'manifestEntry.file',
                value: entry.file,
                constraint: 'must be non-empty file path',
                fix: 'Provide a valid file path in manifest entry',
            });
        }
    }
    return {
        layer: GateLayer.REFERENTIAL,
        status: violations.length > 0 ? GateStatus.FAILED : GateStatus.PASSED,
        passed: violations.length === 0,
        violations,
        duration_ms: 0,
    };
}
/**
 * Layer 4: Protocol Validation
 *
 * Validates RCASD-IVTR+C lifecycle compliance and protocol requirements.
 */
export async function validateLayer4Protocol(context, _enforcer) {
    const violations = [];
    // Skip protocol validation for non-protocol operations
    if (!context.protocolType) {
        return {
            layer: GateLayer.PROTOCOL,
            status: GateStatus.SKIPPED,
            passed: true,
            violations: [],
            duration_ms: 0,
        };
    }
    // Lifecycle gate validation (for spawn/complete operations)
    if (context.operation === 'spawn' || context.operation === 'complete') {
        const protocolType = context.protocolType;
        const lifecycleGates = {
            research: [],
            consensus: ['research'],
            specification: ['research', 'consensus'],
            decomposition: ['research', 'consensus', 'specification'],
            implementation: ['research', 'consensus', 'specification', 'decomposition'],
            validation: ['implementation'],
            testing: ['implementation', 'validation'],
            release: ['implementation', 'validation', 'testing'],
        };
        const requiredGates = lifecycleGates[protocolType] || [];
        if (requiredGates.length > 0) {
            violations.push({
                layer: GateLayer.PROTOCOL,
                severity: ErrorSeverity.INFO,
                code: 'E_LIFECYCLE_PREREQUISITES',
                message: `This operation requires prior stages: ${requiredGates.join(', ')}`,
                field: 'lifecycle',
                constraint: `prerequisites: ${requiredGates.join(', ')}`,
                fix: 'Ensure prior lifecycle stages are complete',
            });
        }
    }
    // Manifest validation (for complete operations)
    if (context.operation === 'complete') {
        const manifestEntry = context.params?.manifestEntry;
        if (manifestEntry) {
            const requiredFields = ['id', 'file', 'title', 'date', 'status', 'agent_type'];
            for (const field of requiredFields) {
                if (!manifestEntry[field]) {
                    violations.push({
                        layer: GateLayer.PROTOCOL,
                        severity: ErrorSeverity.ERROR,
                        code: 'E_MANIFEST_FIELD_MISSING',
                        message: `Manifest entry missing required field: ${field}`,
                        field: `manifestEntry.${field}`,
                        constraint: 'required',
                        fix: `Add ${field} to manifest entry`,
                    });
                }
            }
            const status = manifestEntry.status;
            if (!MANIFEST_STATUSES.includes(status)) {
                violations.push({
                    layer: GateLayer.PROTOCOL,
                    severity: ErrorSeverity.ERROR,
                    code: 'E_INVALID_MANIFEST_STATUS',
                    message: `Invalid manifest status: ${status}`,
                    field: 'manifestEntry.status',
                    value: status,
                    constraint: 'Must be: completed, partial, or blocked',
                    fix: 'Set status to completed, partial, or blocked',
                });
            }
        }
    }
    // Key findings validation for research protocol
    if (context.protocolType === 'research' && context.operation === 'complete') {
        const manifestEntry = context.params?.manifestEntry;
        if (manifestEntry?.key_findings) {
            const findings = manifestEntry.key_findings;
            if (!Array.isArray(findings) ||
                findings.length < GATE_VALIDATION_RULES.KEY_FINDINGS_MIN ||
                findings.length > GATE_VALIDATION_RULES.KEY_FINDINGS_MAX) {
                violations.push({
                    layer: GateLayer.PROTOCOL,
                    severity: ErrorSeverity.ERROR,
                    code: 'E_KEY_FINDINGS_COUNT',
                    message: `Research must have ${GATE_VALIDATION_RULES.KEY_FINDINGS_MIN}-${GATE_VALIDATION_RULES.KEY_FINDINGS_MAX} key findings, got ${Array.isArray(findings) ? findings.length : 0}`,
                    field: 'manifestEntry.key_findings',
                    value: Array.isArray(findings) ? findings.length : findings,
                    constraint: `count: ${GATE_VALIDATION_RULES.KEY_FINDINGS_MIN}-${GATE_VALIDATION_RULES.KEY_FINDINGS_MAX}`,
                    fix: 'Adjust key findings to have 3-7 items',
                });
            }
        }
    }
    // Provenance validation (for implementation protocol)
    if (context.protocolType === 'implementation') {
        const files = context.params?.files;
        if (files && files.length > 0) {
            violations.push({
                layer: GateLayer.PROTOCOL,
                severity: ErrorSeverity.WARNING,
                code: 'E_PROVENANCE_CHECK',
                message: 'Implementation files should include @task provenance tags',
                field: 'files',
                constraint: 'should include @task comments',
                fix: 'Add @task T#### comments to new functions/classes',
            });
        }
    }
    return {
        layer: GateLayer.PROTOCOL,
        status: violations.filter((v) => v.severity === ErrorSeverity.ERROR).length > 0
            ? GateStatus.FAILED
            : GateStatus.PASSED,
        passed: violations.filter((v) => v.severity === ErrorSeverity.ERROR).length === 0,
        violations,
        duration_ms: 0,
    };
}
/**
 * Validation rule definitions for reuse
 */
export const GATE_VALIDATION_RULES = {
    TASK_ID_PATTERN: /^T[0-9]+$/,
    MANIFEST_ID_PATTERN: /^T\d{3,}-[a-z0-9-]+$/,
    DATE_FORMAT_PATTERN: /^\d{4}-\d{2}-\d{2}$/,
    TITLE_MIN_LENGTH: 5,
    TITLE_MAX_LENGTH: 100,
    DESCRIPTION_MIN_LENGTH: 10,
    DESCRIPTION_MAX_LENGTH: 1000,
    VALID_STATUSES: TASK_STATUSES,
    VALID_MANIFEST_STATUSES: MANIFEST_STATUSES,
    VALID_AGENT_TYPES: [
        'research',
        'analysis',
        'specification',
        'implementation',
        'testing',
        'validation',
        'documentation',
        'release',
    ],
    VALID_PRIORITIES: ['critical', 'high', 'medium', 'low'],
    PRIORITY_NUMERIC_MIN: 1,
    PRIORITY_NUMERIC_MAX: 9,
    MAX_DEPTH: 3,
    MAX_SIBLINGS: 0,
    KEY_FINDINGS_MIN: 3,
    KEY_FINDINGS_MAX: 7,
};
/**
 * Helper to check if a field is required for an operation
 */
export function isFieldRequired(domain, operation, field) {
    const requirements = {
        tasks: {
            add: ['title', 'description'],
            update: ['taskId'],
            complete: ['taskId'],
            delete: ['taskId'],
            start: ['taskId'],
        },
        session: {
            start: ['scope'],
        },
    };
    return requirements[domain]?.[operation]?.includes(field) ?? false;
}
// ============================================================================
// Section 7: Workflow Gate Validators
// ============================================================================
/**
 * Valid workflow gate agent names per Section 7.2
 */
export const VALID_WORKFLOW_AGENTS = [
    'coder',
    'testing',
    'qa',
    'cleanup',
    'security',
    'docs',
];
/**
 * Valid workflow gate status values per Section 7.3
 */
export const VALID_WORKFLOW_GATE_STATUSES = [null, 'passed', 'failed', 'blocked'];
/**
 * Validate a workflow gate name
 *
 * @task T3141
 */
export function validateWorkflowGateName(name) {
    return isValidWorkflowGateName(name);
}
/**
 * Validate a workflow gate status value per Section 7.3
 *
 * @task T3141
 */
export function validateWorkflowGateStatus(status) {
    return status === null || status === 'passed' || status === 'failed' || status === 'blocked';
}
/**
 * Validate a gate update operation.
 *
 * @task T3141
 */
export function validateWorkflowGateUpdate(gateName, status, agent, tracker) {
    const violations = [];
    if (!isValidWorkflowGateName(gateName)) {
        violations.push({
            layer: GateLayer.PROTOCOL,
            severity: ErrorSeverity.ERROR,
            code: 'E_INVALID_GATE',
            message: `Invalid workflow gate name: ${gateName}`,
            field: 'gateName',
            value: gateName,
            constraint: `Must be one of: ${WORKFLOW_GATE_SEQUENCE.join(', ')}`,
            fix: `Use a valid gate name: ${WORKFLOW_GATE_SEQUENCE.join(', ')}`,
        });
        return violations;
    }
    if (status !== 'passed' && status !== 'failed') {
        violations.push({
            layer: GateLayer.PROTOCOL,
            severity: ErrorSeverity.ERROR,
            code: 'E_INVALID_GATE_STATUS',
            message: `Invalid gate status for update: ${status}`,
            field: 'status',
            value: status,
            constraint: 'Must be "passed" or "failed" for update operations',
            fix: 'Use status "passed" or "failed"',
        });
    }
    if (agent && tracker) {
        const gateState = tracker.getGateState(gateName);
        if (gateState && agent !== gateState.agent) {
            violations.push({
                layer: GateLayer.PROTOCOL,
                severity: ErrorSeverity.ERROR,
                code: 'E_INVALID_AGENT',
                message: `Agent "${agent}" is not authorized for gate "${gateName}" (expected: ${gateState.agent})`,
                field: 'agent',
                value: agent,
                constraint: `Must be agent: ${gateState.agent}`,
                fix: `Use the correct agent: ${gateState.agent}`,
            });
        }
    }
    if (status === 'passed' && tracker) {
        if (!tracker.canAttempt(gateName)) {
            violations.push({
                layer: GateLayer.PROTOCOL,
                severity: ErrorSeverity.ERROR,
                code: 'E_GATE_DEPENDENCY',
                message: `Cannot pass gate "${gateName}": dependencies not met`,
                field: 'gateName',
                value: gateName,
                constraint: 'All dependency gates must be passed first',
                fix: 'Pass all prerequisite gates first',
            });
        }
    }
    return violations;
}
//# sourceMappingURL=operation-gate-validators.js.map