"use strict";
/**
 * test_service_mode_explicit_only.ts — Stories 2.3 + 2.4
 *
 * Asserts the v1.3 explicit-only service-mode contract:
 *   - WorkflowEngine.run() throws if workflow.mode='service' and caller
 *     did not pass allowServiceMode=true.
 *   - WorkflowEngine.run() succeeds for the same workflow when caller
 *     explicitly opts in.
 *   - ServiceState.promoteTaskToService() refuses silent promotion
 *     (no actor, system actor, missing consent scope).
 *   - ServiceState.promoteTaskToService() succeeds with explicit human
 *     actor + consentScope='task_promotion'.
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const WorkflowEngine_1 = require("./orchestrator/workflow/WorkflowEngine");
const ServiceState_1 = require("./orchestrator/ServiceState");
function assertTrue(cond, label) {
    if (!cond)
        throw new Error(`ASSERT_FAILED[${label}]`);
}
async function main() {
    const tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'service-mode-explicit-'));
    const stateDir = path.join(tmp, '.openlife');
    fs.mkdirSync(stateDir, { recursive: true });
    try {
        // ── Scenario 1: WorkflowEngine refuses service mode without opt-in ──
        const serviceWf = {
            id: 'svc-wf',
            name: 'Service workflow',
            type: 'custom',
            version: '1.0',
            mode: 'service',
            sequence: [{ id: 'step-1', agent: 'dev', action: 'do' }],
        };
        const engine = new WorkflowEngine_1.WorkflowEngine({ stateDir });
        let threwOnImplicit = false;
        let errCode;
        try {
            await engine.run(serviceWf, {});
        }
        catch (e) {
            threwOnImplicit = true;
            errCode = e.code;
        }
        assertTrue(threwOnImplicit, 'scenario 1: implicit service run rejected');
        assertTrue(errCode === 'service_mode_requires_explicit_opt_in', `scenario 1: error code (got ${errCode})`);
        console.log('[2.3] scenario 1 (implicit service run refused) ✓');
        // ── Scenario 2: WorkflowEngine accepts service mode with opt-in ─────
        const state = await engine.run(serviceWf, {}, { allowServiceMode: true });
        assertTrue(state.status === 'completed' || state.status === 'awaiting_input' || state.status === 'failed', 'scenario 2: service run executes');
        assertTrue(state.context?.__mode === 'service', 'scenario 2: mode plumbed to context');
        console.log('[2.3] scenario 2 (explicit service run accepted) ✓');
        // ── Scenario 3: task workflow runs without any flag ────────────────
        const taskWf = {
            id: 'task-wf',
            name: 'Task workflow',
            type: 'custom',
            version: '1.0',
            sequence: [{ id: 'step-1', agent: 'dev', action: 'do' }],
        };
        const taskState = await engine.run(taskWf, {});
        assertTrue(taskState.context?.__mode === 'task', 'scenario 3: defaults to task mode');
        console.log('[2.3] scenario 3 (task is default) ✓');
        // ── Scenario 4: promoteTaskToService refuses missing actor ─────────
        // ServiceStateStore reads .artifacts/workspaces/<wsId>/... via process.cwd(),
        // so run the test from within tmp.
        const origCwd = process.cwd();
        process.chdir(tmp);
        const svcStore = new ServiceState_1.ServiceStateStore('test-ws');
        // Minimal MissionState — ServiceStateStore.promoteTaskToService only
        // reads .taskId, .goal, and optional .consequenceThoughtTrace.
        const mission = {
            taskId: 'mission-1',
            goal: 'test goal',
        };
        let threw1 = false;
        let err1;
        try {
            svcStore.promoteTaskToService(mission, 'svc-from-missing-actor', undefined);
        }
        catch (e) {
            threw1 = true;
            err1 = e.code;
        }
        assertTrue(threw1, 'scenario 4: missing actor refused');
        assertTrue(err1 === 'task_promotion_requires_human_actor', `scenario 4: error code (got ${err1})`);
        console.log('[2.4] scenario 4 (missing actor refused) ✓');
        // ── Scenario 5: promoteTaskToService refuses system actor ──────────
        let threw2 = false;
        let err2;
        try {
            svcStore.promoteTaskToService(mission, 'svc-from-system', undefined, { actor: 'system', consentScope: 'task_promotion' });
        }
        catch (e) {
            threw2 = true;
            err2 = e.code;
        }
        assertTrue(threw2, 'scenario 5: system actor refused');
        assertTrue(err2 === 'task_promotion_requires_human_actor', `scenario 5: error code (got ${err2})`);
        console.log('[2.4] scenario 5 (system actor refused) ✓');
        // ── Scenario 6: promoteTaskToService refuses missing consent scope ─
        let threw3 = false;
        let err3;
        try {
            svcStore.promoteTaskToService(mission, 'svc-no-scope', undefined, { actor: 'rafa' });
        }
        catch (e) {
            threw3 = true;
            err3 = e.code;
        }
        assertTrue(threw3, 'scenario 6: missing consent scope refused');
        assertTrue(err3 === 'task_promotion_requires_consent_scope', `scenario 6: error code (got ${err3})`);
        console.log('[2.4] scenario 6 (missing consent scope refused) ✓');
        // ── Scenario 7: explicit human actor + scope succeeds ──────────────
        const svc = svcStore.promoteTaskToService(mission, 'svc-ok', 'real promotion', {
            actor: 'rafa',
            consentScope: 'task_promotion',
            reason: 'long-running research',
        });
        assertTrue(svc.serviceId === 'svc-ok', 'scenario 7: service created');
        assertTrue(svc.missionIds.includes('mission-1'), 'scenario 7: mission attached');
        console.log('[2.4] scenario 7 (explicit promotion succeeds) ✓');
        process.chdir(origCwd);
        console.log('TEST_SERVICE_MODE_EXPLICIT_ONLY_OK');
    }
    finally {
        try {
            process.chdir(path.dirname(tmp));
        }
        catch { /* ignore */ }
        fs.rmSync(tmp, { recursive: true, force: true });
    }
}
main().catch((err) => {
    console.error('[service-mode-explicit] FAILED:', err instanceof Error ? err.message : err);
    process.exit(1);
});
