<!-- SOLIDABILITY-WORLD · part 44 -->
;
      narrate(`AI Drive stopped. You have manual control.`);
      setTimeout(clearNarration, 2000);
      setMode('WALK');
      return true;
    }
    return false;
  }

  function isAIDriving() { return aiDriving; }

  // Pause AI (for human intervention) — preserves navigation state
  let pausedNav = null;
  function pauseAI() {
    if (navigating) {
      pausedNav = { path: [...navPath], index: navIndex, room: focusedRoom };
      navigating = false;
      clearPathTrail();
      // Don't clear aiDriving — we're paused, not stopped
      return true;
    }
    return false;
  }

  // Resume AI from paused state
  function resumeAI(destination) {
    if (pausedNav && pausedNav.path.length > 0) {
      // Resume existing navigation
      navPath = pausedNav.path;
      navIndex = pausedNav.index;
      focusedRoom = pausedNav.room;
      navigating = true;
      aiDriving = true;
      setMode('AI_DRIVE');
      showPathTrail(navPath);
      narrate(`Resuming navigation.`);
      pausedNav = null;
      return true;
    } else if (destination) {
      // New destination
      return aiDriveTo(destination, `Resuming with new destination.`);
    } else if (aiDriving) {
      // Was driving but no nav state — just re-engage
      setMode('AI_DRIVE');
      return true;
    }
    return false;
  }

  function getFocusedRoom() { return focusedRoom; }

  // Per-frame update
  function update(dt) {
    // Don't navigate while human is inspecting
    if (typeof SWIntervene !== 'undefined' && SWIntervene.isPaused()) return;
    // Stop investigator if human takes manual control
    if (typeof SWInvestigator !== 'undefined' && SWInvestigator.isInvestigating()) {
      // Investigator uses aiDriveTo, which respects manual takeover
    }
    if (navigating) updateNavigate(dt);
    if (mode === 'LOOK') updateLookCamera();
  }

  // Push history on significant moves (called externally or on teleport)
  function init() {
    buildUI();
    // Push starting position
    setTimeout(() => pushHistory(), 1000);
  }

  return {
    init, update, setMode, getMode,
    navigateTo, focusNearest, scan, goReturn,
    pushHistory, handleCommand,
    aiDriveTo, startTour, findProblem, goUpstairs, stopAI, isAIDriving,
    pauseAI, resumeAI, getFocusedRoom,
    narrate
  };
})();


===== FILE: public/solidability-world/js/sw-intervene.js =====
// Solidability World — Human Intervention System
// Tap any wall during WALK, AI DRIVE, or HYPER DRIVE to pause and inspect.
// Preserves position, camera, destination, route, and mode.
// Explicit RESUME / REDIRECT / MANUAL / END actions. Searchable history.

const SWIntervene = (() => {
  let paused = false;
  let pausedState = null; // {mode, position, cameraYaw, destination, navPath, navIndex}
  let inspectionLog = [];
  let currentInspection = null;

  // Pause movement and open inspection
  function intervene(room, wallInfo) {
    if (paused) return; // already inspecting

    const player = SWEngine.getPlayer();
    const hyper = SWHyper;

    // Capture full state
    pausedState = {
      mode: hyper.getMode(),
      aiDriving: hyper.isAIDriving(),
      position: {
        x: player.position.x,
        y: player.position.y,
        z: player.position.z,
      },
      destination: hyper.getFocusedRoom ? hyper.getFocusedRoom() : null,
      timestamp: new Date().toISOString(),
    };

    paused = true;

    // Pause AI without losing state
    if (hyper.isAIDriving()) {
      hyper.pauseAI(); // pause, don't stop
    }

    // Log the intervention
    currentInspection = {
      id: 'insp_' + Date.now(),
      timestamp: pausedState.timestamp,
      mode: pausedState.mode,
      district: room.district || 'unknown',
      room: room.label,
      roomKey: room.key,
      file: room.filePath || 'n/a',
      wall: wallInfo || 'building face',
      action: 'inspect',
    };
    inspectionLog.push(currentInspection);
    if (inspectionLog.length > 100) inspectionLog.shift();

    // MERGED: Show unified panel (glass details + intervention actions)
    // Instead of two overlapping panels, the glass now carries the pause UI
    SWGlass.show(room, {
      paused: true,
      pauseInfo: {
        mode: pausedState.mode,
        position: pausedState.position,
      }
    });
  }

  // Legacy: separate UI removed — merged into glass panel (2026-10-08)
  // showInterventionUI now a no-op; SWGlass.show(room, {paused:true}) carries the UI
  function showInterventionUI(room) { /* merged into glass */ }

  function hideUI() {
    // Glass handles its own visibility now
  }

  // RESUME: continue from paused state, revalidate route
  function resume() {
    if (!paused || !pausedState) return;
    hideUI();
    SWGlass.hide();

    const hyper = SWHyper;
    // Revalidate: check if destination still exists
    if (pausedState.destination) {
      const layout = SWWorld.getLayout();
      const stillExists = layout.rooms.some(r => r.key === pausedState.d