"use strict";
/**
 * VortexAuthorityGuard — enforces @vortex exclusive authority over
 * irreversible, outward-facing operations in the autonomous path.
 *
 * Phase 3 (Governance on Every Mission) of the autonomous-agent milestone.
 *
 * Locked rule (project constitution + agent-authority.md): git push, gh PR
 * create/merge, and npm publish are @vortex-exclusive. An autonomous mission
 * MUST NOT perform them without EXPLICIT user authorization.
 *
 * The authorization is a token the user sets deliberately
 * (OPENLIFE_VORTEX_TOKEN) and that a mission carries in its context
 * (context.vortexAuthorization). No token set → the capability simply cannot
 * be authorized, so the autonomous agent can never push on its own. This is
 * fail-closed by design: the absence of configuration denies, never allows.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.VortexAuthorityGuard = void 0;
const crypto_1 = require("crypto");
/** Patterns for @vortex-exclusive operations. Case-insensitive substring/regex. */
const VORTEX_PATTERNS = [
    { op: 'git-push', re: /\bgit\s+push\b/i },
    { op: 'git-force-push', re: /\bgit\s+push\b.*--force|\bforce[- ]?push\b/i },
    { op: 'gh-pr-create', re: /\bgh\s+pr\s+create\b/i },
    { op: 'gh-pr-merge', re: /\bgh\s+pr\s+merge\b/i },
    { op: 'npm-publish', re: /\bnpm\s+publish\b/i },
    { op: 'release', re: /\b(publish|ship)\s+(to\s+)?(npm|registry|production)\b/i },
];
class VortexAuthorityGuard {
    /**
     * Inspect a mission goal + context. Does NOT throw.
     *
     * @param goal    the mission goal text
     * @param context optional mission context; context.vortexAuthorization is
     *                the one-shot token the caller presents.
     */
    check(goal, context) {
        const text = String(goal || '');
        const matchedOps = [];
        for (const { op, re } of VORTEX_PATTERNS) {
            if (re.test(text))
                matchedOps.push(op);
        }
        const requiresAuthority = matchedOps.length > 0;
        if (!requiresAuthority) {
            return { requiresAuthority: false, authorized: true, matchedOps: [] };
        }
        const presented = typeof context?.vortexAuthorization === 'string'
            ? context.vortexAuthorization
            : '';
        const authorized = this.tokenValid(presented);
        return { requiresAuthority: true, authorized, matchedOps };
    }
    /**
     * Constant-time compare against the configured token. Fail-closed: if no
     * token is configured, NOTHING authorizes (the autonomous agent cannot
     * push). An empty presented token never matches.
     */
    tokenValid(presented) {
        const configured = (process.env.OPENLIFE_VORTEX_TOKEN || '').trim();
        if (!configured)
            return false; // fail-closed
        if (!presented)
            return false;
        const a = Buffer.from(presented);
        const b = Buffer.from(configured);
        if (a.length !== b.length)
            return false;
        try {
            return (0, crypto_1.timingSafeEqual)(a, b);
        }
        catch {
            return false;
        }
    }
}
exports.VortexAuthorityGuard = VortexAuthorityGuard;
