/**
 * Validator role contracts — types consumed by the SDK tools (T10511) and the
 * Max-N runtime (T10512) to express the verdict a Validator agent returns
 * after reviewing a Worker submission against a task's acceptance criteria.
 *
 * The Validator is a NEW canonical role in the orchestration hierarchy,
 * orthogonal to the existing Orchestrator → Lead → Worker triad. A Validator
 * does NOT execute work and does NOT spawn other agents — it ONLY attests or
 * rejects work claimed-done by another agent, per-AC.
 *
 * Identity triad:
 *  - `agentId` follows the pattern `validator-<discriminator>` (e.g.
 *    `validator-prime`, `validator-sec-001`).
 *  - `role` is `'validator'` (see {@link AgentRole}).
 *  - `sigilCard` is reused as-is from the existing peer/memory layer when
 *    the Validator is registered as a CANT-defined persona.
 *
 * Design constraints (ADR-055 / D028 boundary rules):
 *  - Lives in `packages/contracts/` — ZERO runtime dependencies (Zod only).
 *  - Consumed by `packages/cleo-sdk-tools/` (T10511) and `packages/core/` (T10512).
 *  - No cross-package relative imports.
 *
 * @module validator
 * @task T10510
 * @epic T10383 (E-VALIDATOR-ROLE)
 * @saga T10377 (SG-IVTR-AC-BINDING)
 */
import { z } from 'zod';
/**
 * Frozen list of canonical {@link AgentRole} values for runtime iteration
 * (e.g. CLI flag validation, registry seeding).
 *
 * @task T10510
 * @epic T10383
 */
export const AGENT_ROLES = ['orchestrator', 'lead', 'worker', 'validator'];
/**
 * Type guard for {@link AgentRole}. Returns `true` when `value` is one of the
 * four canonical role strings.
 *
 * @task T10510
 */
export function isAgentRole(value) {
    return typeof value === 'string' && AGENT_ROLES.includes(value);
}
// ============================================================================
// Zod schemas — runtime validation
// ============================================================================
/**
 * Regex validating the canonical Validator agentId pattern
 * `validator-<discriminator>`. The discriminator is `[a-z0-9][a-z0-9-]*`
 * (lowercase alphanumeric + hyphens, must start with alphanum).
 *
 * Examples that MATCH: `validator-prime`, `validator-sec-001`, `validator-a`.
 * Examples that DO NOT match: `validator-`, `Validator-prime`, `validator--x`.
 *
 * @task T10510
 */
export const VALIDATOR_ID_REGEX = /^validator-[a-z0-9][a-z0-9-]*$/;
/**
 * Zod schema for {@link ValidatorFinding}. Enforces the AC-id presence,
 * status enum, non-empty reasoning, and ISO-8601 timestamp shape.
 *
 * @task T10510
 */
export const validatorFindingSchema = z.object({
    acId: z.string().min(1, 'acId must be non-empty'),
    status: z.enum(['pass', 'fail', 'inconclusive']),
    reasoning: z.string().min(1, 'reasoning must be non-empty'),
    evidenceRefs: z.array(z.string()).optional(),
    checkedAt: z.string().min(1, 'checkedAt must be a non-empty ISO-8601 string'),
});
/**
 * Zod schema for {@link ValidatorAttestation}. Enforces:
 *  - `verdict === 'attest'`
 *  - `validatorId` matches {@link VALIDATOR_ID_REGEX}
 *  - `findings` non-empty AND every entry has `status === 'pass'`
 *  - `schemaVersion === '1'`
 *
 * @task T10510
 */
export const validatorAttestationSchema = z.object({
    verdict: z.literal('attest'),
    taskId: z.string().min(1),
    validatorId: z
        .string()
        .regex(VALIDATOR_ID_REGEX, 'validatorId must match the pattern validator-<discriminator>'),
    findings: z
        .array(validatorFindingSchema)
        .min(1, 'attestation must contain at least one finding')
        .refine((findings) => findings.every((f) => f.status === 'pass'), 'attestation requires every finding to have status="pass"'),
    summary: z.string().optional(),
    attestedAt: z.string().min(1),
    schemaVersion: z.literal('1'),
});
/**
 * Zod schema for {@link ValidatorRejection}. Enforces:
 *  - `verdict === 'reject'`
 *  - `validatorId` matches {@link VALIDATOR_ID_REGEX}
 *  - `findings` non-empty AND at least one entry has `status !== 'pass'`
 *  - `summary` non-empty (rejection rationale is mandatory)
 *  - `schemaVersion === '1'`
 *
 * @task T10510
 */
export const validatorRejectionSchema = z.object({
    verdict: z.literal('reject'),
    taskId: z.string().min(1),
    validatorId: z
        .string()
        .regex(VALIDATOR_ID_REGEX, 'validatorId must match the pattern validator-<discriminator>'),
    findings: z
        .array(validatorFindingSchema)
        .min(1, 'rejection must contain at least one finding')
        .refine((findings) => findings.some((f) => f.status !== 'pass'), 'rejection requires at least one finding with status "fail" or "inconclusive"'),
    summary: z.string().min(1, 'rejection summary must be non-empty'),
    remediationHints: z.array(z.string()).optional(),
    rejectedAt: z.string().min(1),
    schemaVersion: z.literal('1'),
});
/**
 * Zod schema for the {@link ValidatorVerdict} discriminated union.
 * Routes parsing through the `verdict` discriminant.
 *
 * @task T10510
 */
export const validatorVerdictSchema = z.discriminatedUnion('verdict', [
    validatorAttestationSchema,
    validatorRejectionSchema,
]);
// ============================================================================
// Type guards
// ============================================================================
/**
 * Type guard validating that `value` conforms to {@link ValidatorAttestation}.
 * Internally uses {@link validatorAttestationSchema}.
 *
 * @task T10510
 */
export function isValidatorAttestation(value) {
    return validatorAttestationSchema.safeParse(value).success;
}
/**
 * Type guard validating that `value` conforms to {@link ValidatorRejection}.
 * Internally uses {@link validatorRejectionSchema}.
 *
 * @task T10510
 */
export function isValidatorRejection(value) {
    return validatorRejectionSchema.safeParse(value).success;
}
/**
 * Type guard validating that `value` conforms to {@link ValidatorVerdict}
 * (either an attestation or a rejection). Internally uses
 * {@link validatorVerdictSchema}.
 *
 * @task T10510
 */
export function isValidatorVerdict(value) {
    return validatorVerdictSchema.safeParse(value).success;
}
//# sourceMappingURL=index.js.map