/**
 * @internal
 * consistency/registry.mjs — rule registry for the C15 cross-artifact
 * consistency validator. Mirrors the shape of gate/registry.mjs so that a
 * single rule is:
 *
 *   {
 *     id:          string,                       // e.g. 'r1-ac-coverage'
 *     severity:    'error' | 'warn',
 *     stages:      Array<string>,                // ['plan','execute','verify','review','ship']
 *     description: string,
 *     check:       async ({taskDir, parsed}) => {
 *                    status: 'pass' | 'fail' | 'skip',
 *                    drift: Array<object>,
 *                    reason: string
 *                  }
 *   }
 *
 * Module-scope singleton. Built-in rule modules self-register via the
 * `rules/index.mjs` barrel, imported eagerly by check.mjs.
 */
const registry = new Map();
/**
 * Register a rule. Re-registering the same id replaces the previous entry
 * (supports hot-reload in tests).
 *
 * @internal
 */
export function registerRule(rule) {
    if (!rule || typeof rule !== 'object') {
        throw new Error('registerRule: rule must be an object');
    }
    if (typeof rule.id !== 'string' || !rule.id) {
        throw new Error('registerRule: rule.id must be a non-empty string');
    }
    if (rule.severity !== 'error' && rule.severity !== 'warn') {
        throw new Error(`registerRule(${rule.id}): severity must be "error" or "warn" (got ${rule.severity})`);
    }
    if (!Array.isArray(rule.stages) || rule.stages.length === 0) {
        throw new Error(`registerRule(${rule.id}): stages must be a non-empty array`);
    }
    if (typeof rule.check !== 'function') {
        throw new Error(`registerRule(${rule.id}): check must be a function`);
    }
    if (typeof rule.description !== 'string') {
        throw new Error(`registerRule(${rule.id}): description must be a string`);
    }
    registry.set(rule.id, rule);
    return rule;
}
/**
 * List all registered rules, optionally filtered to those applicable to a
 * specific stage.
 *
 * @internal
 */
export function listRules({ stage } = {}) {
    const all = Array.from(registry.values());
    if (!stage)
        return all;
    return all.filter((r) => r.stages.includes(stage));
}
/**
 * Lookup a single rule by id. Returns undefined when unknown.
 *
 * @internal
 */
export function getRule(id) {
    return registry.get(id);
}
/**
 * Test-only helper — drop every registered rule.
 *
 * @internal
 */
export function __resetRegistryForTests() {
    registry.clear();
}
/**
 * Test-only helper — uniformly-named alias for the in-process cmd harness
 * (run-cmd.mjs). Built-in rules self-register via the `rules/index.mjs`
 * barrel at module-import time, which ESM evaluates exactly once per
 * process — so the harness deliberately does NOT call this by default
 * (clearing here would leave subsequent cmd invocations looking at an empty
 * registry). Tests that need an empty registry import this name explicitly.
 *
 * @internal
 */
export function __resetCaches() {
    registry.clear();
}
//# sourceMappingURL=registry.mjs.map