// SPEC: PJ2026-01040111 long-running Workbench observation.
// Responsibility: Analyzer artifact IO, YAML-derived config parsing, JSONL tailing, focus windows, and sample compaction source fragment.

export function nodeWebObserveAnalyzerIoSource(): string {
  return String.raw`async function readJson(file) {
  try { return JSON.parse(await readFile(file, "utf8")); } catch { return null; }
}

async function readCommandState(rootDir) {
  const buckets = {};
  for (const bucket of ["pending", "processing", "done", "failed", "abandoned"]) {
    buckets[bucket] = await readCommandBucket(path.join(rootDir, "commands", bucket), bucket);
  }
  return {
    pendingCount: buckets.pending.count,
    processingCount: buckets.processing.count,
    doneCount: buckets.done.count,
    failedCount: buckets.failed.count,
    abandonedCount: buckets.abandoned.count,
    pending: buckets.pending.items,
    processing: buckets.processing.items,
    failed: buckets.failed.items.slice(0, 12),
    abandoned: buckets.abandoned.items.slice(0, 20),
    summary: {
      backlogCount: buckets.pending.count + buckets.processing.count,
      oldestPendingAgeSeconds: buckets.pending.oldestAgeSeconds,
      oldestProcessingAgeSeconds: buckets.processing.oldestAgeSeconds,
      valuesRedacted: true
    },
    valuesRedacted: true
  };
}

async function readCommandBucket(dir, bucket) {
  let names = [];
  try {
    names = (await readdir(dir)).filter((name) => name.endsWith(".json")).sort();
  } catch (error) {
    if (!error || error.code !== "ENOENT") jsonlReadIssues.push({ file: path.basename(dir), kind: "command-dir-read-error", code: error && error.code ? String(error.code) : null, errorMessage: limitText(error && error.message ? error.message : String(error), 240) });
    return { bucket, count: 0, oldestAgeSeconds: null, items: [] };
  }
  const items = [];
  for (const name of names.slice(0, 200)) {
    const file = path.join(dir, name);
    const parsed = await readJson(file) || {};
    let meta = null;
    try { meta = await stat(file); } catch {}
    const timestamp = parsed.createdAt || parsed.abandonedAt || parsed.completedAt || parsed.failedAt || (meta ? meta.mtime.toISOString() : null);
    const timestampMs = Date.parse(String(timestamp || ""));
    items.push({
      bucket,
      id: parsed.id || parsed.commandId || name.replace(/[.]json$/u, ""),
      type: parsed.type || parsed.command?.type || null,
      createdAt: parsed.createdAt || null,
      completedAt: parsed.completedAt || null,
      failedAt: parsed.failedAt || null,
      abandonedAt: parsed.abandonedAt || null,
      reason: parsed.reason || parsed.error?.message || null,
      ageSeconds: Number.isFinite(timestampMs) ? Math.max(0, Math.round((Date.now() - timestampMs) / 1000)) : null,
      mtime: meta ? meta.mtime.toISOString() : null,
      valuesRedacted: true
    });
  }
  const ages = items.map((item) => item.ageSeconds).filter((value) => Number.isFinite(value));
  return { bucket, count: names.length, oldestAgeSeconds: ages.length > 0 ? Math.max(...ages) : null, items };
}

function buildToolFindings({ manifest, heartbeat, commandState }) {
  const findings = [];
  const diagnostics = heartbeatDiagnostics(manifest, heartbeat);
  const startupReadiness = toolStartupReadiness(manifest, heartbeat);
  if (startupReadiness !== null) {
    findings.push({
      id: "tool-target-page-not-ready",
      severity: "red",
      summary: "web-probe observe target page did not reach the expected Workbench app shell; treat this as probe setup/runtime access blocker before interpreting business turns or frontend hotspots",
      count: 1,
      reason: startupReadiness.reason,
      rootCause: startupReadiness.reason === "nav-access-denied" ? "web_probe_target_nav_access_denied" : startupReadiness.reason === "workbench-blank-document" ? "web_probe_target_blank_workbench_document" : "web_probe_target_page_not_ready",
      rootCauseStatus: "confirmed-from-startup-readiness",
      rootCauseConfidence: "high",
      nextAction: "Fix the selected node/lane Web access or Workbench shell loading first, then rerun observe start and performanceCapture; do not treat an empty performance report from this run as a business performance result.",
      readiness: startupReadiness,
      valuesRedacted: true
    });
  }
  if (diagnostics.heartbeatStale) {
    findings.push({
      id: "tool-runner-heartbeat-stale",
      severity: "red",
      summary: "web-probe observe runner heartbeat is stale; treat this as observer tooling failure, not Workbench behavior",
      count: 1,
      diagnostics,
      valuesRedacted: true
    });
  }
  if ((commandState?.pendingCount ?? 0) > 0 || (commandState?.processingCount ?? 0) > 0) {
    findings.push({
      id: "tool-pending-commands-unconsumed",
      severity: "red",
      summary: "web-probe observe has pending/processing control commands that were not consumed by the runner",
      count: (commandState?.pendingCount ?? 0) + (commandState?.processingCount ?? 0),
      pending: (commandState?.pending ?? []).slice(0, 12),
      processing: (commandState?.processing ?? []).slice(0, 12),
      valuesRedacted: true
    });
  }
  if ((commandState?.abandonedCount ?? 0) > 0) {
    findings.push({
      id: "tool-commands-abandoned",
      severity: "info",
      summary: "web-probe observe force-stop abandoned queued commands; do not interpret these as Workbench command failures",
      count: commandState.abandonedCount,
      commands: (commandState.abandoned ?? []).slice(0, 20),
      valuesRedacted: true
    });
  }
  if (heartbeat?.forceStop || manifest?.forceStop) {
    findings.push({
      id: "tool-runner-force-stopped",
      severity: "info",
      summary: "web-probe observe runner was stopped by the CLI outside the command queue",
      count: 1,
      forceStop: heartbeat?.forceStop || manifest?.forceStop,
      valuesRedacted: true
    });
  }
  return findings;
}

function toolStartupReadiness(manifest, heartbeat) {
  const candidates = [
    heartbeat?.error?.navigationReadiness,
    heartbeat?.error?.details?.readiness,
    heartbeat?.error?.details?.readinessAfterWait,
    heartbeat?.error?.details?.readinessBeforeClick,
    manifest?.error?.navigationReadiness,
    manifest?.error?.details?.readiness,
    manifest?.error?.details?.readinessAfterWait,
    manifest?.error?.details?.readinessBeforeClick,
  ];
  for (const candidate of candidates) {
    const readiness = candidate && typeof candidate === "object" && !Array.isArray(candidate) ? candidate : null;
    if (!readiness) continue;
    const snapshot = readiness.snapshot && typeof readiness.snapshot === "object" && !Array.isArray(readiness.snapshot) ? readiness.snapshot : readiness;
    const reason = typeof readiness.reason === "string" && readiness.reason ? readiness.reason : typeof snapshot.reason === "string" && snapshot.reason ? snapshot.reason : null;
    if (reason === null) continue;
    return {
      reason,
      path: typeof snapshot.path === "string" ? snapshot.path : null,
      search: typeof snapshot.search === "string" ? snapshot.search : null,
      blockedReason: typeof snapshot.blockedReason === "string" ? snapshot.blockedReason : null,
      readyState: typeof snapshot.readyState === "string" ? snapshot.readyState : null,
      workbenchShellVisible: snapshot.workbenchShellVisible === true,
      sessionCreatePresent: snapshot.sessionCreatePresent === true,
      sessionCreateVisible: snapshot.sessionCreateVisible === true,
      sessionRailPresent: snapshot.sessionRailPresent === true,
      commandInputPresent: snapshot.commandInputPresent === true,
      activeTabPresent: snapshot.activeTabPresent === true,
      loginVisible: snapshot.loginVisible === true,
      bodyTextBytes: Number.isFinite(Number(snapshot.bodyTextBytes)) ? Number(snapshot.bodyTextBytes) : null,
      bodyTextHash: typeof snapshot.bodyTextHash === "string" ? snapshot.bodyTextHash : null,
      valuesRedacted: true
    };
  }
  return null;
}

function heartbeatDiagnostics(manifest, heartbeat) {
  const status = String(heartbeat?.status || manifest?.status || "");
  const terminal = /^(completed|failed|force-stopped|stopped|abandoned)$/u.test(status);
  const sampleIntervalMs = Number(manifest?.sampling?.sampleIntervalMs) || 5000;
  const staleAfterMs = Math.max(60000, sampleIntervalMs * 3);
  const updatedAt = heartbeat?.updatedAt || heartbeat?.lastSampleAt || null;
  const updatedMs = Date.parse(String(updatedAt || ""));
  const ageSeconds = Number.isFinite(updatedMs) ? Math.max(0, Math.round((Date.now() - updatedMs) / 1000)) : null;
  const heartbeatStale = !terminal && (!Number.isFinite(updatedMs) || Date.now() - updatedMs > staleAfterMs);
  return {
    status: status || null,
    terminal,
    updatedAt,
    heartbeatAgeSeconds: ageSeconds,
    heartbeatStale,
    heartbeatStaleAfterSeconds: Math.round(staleAfterMs / 1000),
    sampleSeq: heartbeat?.sampleSeq ?? null,
    commandSeq: heartbeat?.commandSeq ?? null,
    activeCommandId: heartbeat?.activeCommandId ?? null,
    valuesRedacted: true
  };
}

function safeArchivePrefix(value) {
  const text = String(value || "").trim();
  if (!text) return "";
  if (!/^[A-Za-z0-9_.-]+$/u.test(text) || text.includes("..")) throw new Error("unsafe archive prefix: " + text);
  return text;
}

function positiveNumber(value, fallback) {
  const parsed = Number(value);
  return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
}

function requiredPositiveThreshold(raw, key) {
  const parsed = Number(raw?.[key]);
  if (!Number.isFinite(parsed) || parsed <= 0) {
    throw new Error("UNIDESK_WEB_OBSERVE_ALERT_THRESHOLDS_JSON requires positive " + key + "; configure config/hwlab-node-lanes.yaml webProbe.alertThresholds");
  }
  return parsed;
}

function parseAlertThresholds(value) {
  if (!value) {
    throw new Error("UNIDESK_WEB_OBSERVE_ALERT_THRESHOLDS_JSON is required; configure config/hwlab-node-lanes.yaml webProbe.alertThresholds for the selected node/lane");
  }
  const raw = (() => {
    try { return JSON.parse(value); } catch (error) { throw new Error("UNIDESK_WEB_OBSERVE_ALERT_THRESHOLDS_JSON is invalid JSON: " + (error instanceof Error ? error.message : String(error))); }
  })();
  const sessionRailFallbackRatio = requiredPositiveThreshold(raw, "sessionRailFallbackRatio");
  if (sessionRailFallbackRatio > 1) {
    throw new Error("UNIDESK_WEB_OBSERVE_ALERT_THRESHOLDS_JSON sessionRailFallbackRatio must be <= 1");
  }
  return {
    sameOriginApiSlowMs: requiredPositiveThreshold(raw, "sameOriginApiSlowMs"),
    partialApiSlowMs: requiredPositiveThreshold(raw, "partialApiSlowMs"),
    longLivedStreamOpenSlowMs: requiredPositiveThreshold(raw, "longLivedStreamOpenSlowMs"),
    visibleLoadingSlowMs: requiredPositiveThreshold(raw, "visibleLoadingSlowMs"),
    turnTimingSampleSlackSeconds: requiredPositiveThreshold(raw, "turnTimingSampleSlackSeconds"),
    turnElapsedSevereTimeoutSeconds: requiredPositiveThreshold(raw, "turnElapsedSevereTimeoutSeconds"),
    domEvaluateTimeoutRedCount: requiredPositiveThreshold(raw, "domEvaluateTimeoutRedCount"),
    domEvaluateTimeoutRedWindowMs: requiredPositiveThreshold(raw, "domEvaluateTimeoutRedWindowMs"),
    screenshotTimeoutRedCount: requiredPositiveThreshold(raw, "screenshotTimeoutRedCount"),
    pageErrorRedCount: requiredPositiveThreshold(raw, "pageErrorRedCount"),
    longTaskRedMs: requiredPositiveThreshold(raw, "longTaskRedMs"),
    longAnimationFrameRedMs: requiredPositiveThreshold(raw, "longAnimationFrameRedMs"),
    eventLoopGapRedMs: requiredPositiveThreshold(raw, "eventLoopGapRedMs"),
    browserProcessSampleIntervalMs: requiredPositiveThreshold(raw, "browserProcessSampleIntervalMs"),
    requestRateBucketMs: requiredPositiveThreshold(raw, "requestRateBucketMs"),
    requestRateTotalRedPerMinute: requiredPositiveThreshold(raw, "requestRateTotalRedPerMinute"),
    requestRatePageRedPerMinute: requiredPositiveThreshold(raw, "requestRatePageRedPerMinute"),
    requestRateApiPathRedPerMinute: requiredPositiveThreshold(raw, "requestRateApiPathRedPerMinute"),
    browserTotalRssRedMb: requiredPositiveThreshold(raw, "browserTotalRssRedMb"),
    browserProcessRssRedMb: requiredPositiveThreshold(raw, "browserProcessRssRedMb"),
    browserRssGrowthRedMb: requiredPositiveThreshold(raw, "browserRssGrowthRedMb"),
    browserRssGrowthWindowMs: requiredPositiveThreshold(raw, "browserRssGrowthWindowMs"),
    playwrightResponsivenessRedMs: requiredPositiveThreshold(raw, "playwrightResponsivenessRedMs"),
    playwrightResponsivenessTimeoutRedCount: requiredPositiveThreshold(raw, "playwrightResponsivenessTimeoutRedCount"),
    cdpMetricsTimeoutRedCount: requiredPositiveThreshold(raw, "cdpMetricsTimeoutRedCount"),
    uncommandedStateChangeCommandWindowMs: requiredPositiveThreshold(raw, "uncommandedStateChangeCommandWindowMs"),
    scrollJumpCommandWindowMs: requiredPositiveThreshold(raw, "scrollJumpCommandWindowMs"),
    scrollJumpFromY: requiredPositiveThreshold(raw, "scrollJumpFromY"),
    scrollJumpToY: requiredPositiveThreshold(raw, "scrollJumpToY"),
    sessionRailFallbackRatio,
    crossPageProjectionDivergenceRedMs: positiveNumber(raw.crossPageProjectionDivergenceRedMs, requiredPositiveThreshold(raw, "visibleLoadingSlowMs")),
    source: "yaml-env",
  };
}

function parseBrowserFreezePolicy(value) {
  if (!value) {
    throw new Error("UNIDESK_WEB_OBSERVE_BROWSER_FREEZE_POLICY_JSON is required; configure config/hwlab-node-lanes.yaml webProbe.browserFreezePolicy for the selected node/lane");
  }
  const raw = (() => {
    try { return JSON.parse(value); } catch (error) { throw new Error("UNIDESK_WEB_OBSERVE_BROWSER_FREEZE_POLICY_JSON is invalid JSON: " + (error instanceof Error ? error.message : String(error))); }
  })();
  const memory = requiredPolicyRecord(raw, "memory", "webProbe.browserFreezePolicy");
  const responsiveness = requiredPolicyRecord(raw, "responsiveness", "webProbe.browserFreezePolicy");
  const cdp = requiredPolicyRecord(raw, "cdp", "webProbe.browserFreezePolicy");
  const kill = requiredPolicyRecord(raw, "kill", "webProbe.browserFreezePolicy");
  return {
    enabled: requiredPolicyBoolean(raw, "enabled", "webProbe.browserFreezePolicy"),
    blockerWindowMs: requiredPolicyPositiveNumber(raw, "blockerWindowMs", "webProbe.browserFreezePolicy"),
    memory: {
      totalRssBlockerMb: requiredPolicyPositiveNumber(memory, "totalRssBlockerMb", "webProbe.browserFreezePolicy.memory"),
      processRssBlockerMb: requiredPolicyPositiveNumber(memory, "processRssBlockerMb", "webProbe.browserFreezePolicy.memory"),
      growthBlockerMb: requiredPolicyPositiveNumber(memory, "growthBlockerMb", "webProbe.browserFreezePolicy.memory"),
    },
    responsiveness: {
      latencyBlockerMs: requiredPolicyPositiveNumber(responsiveness, "latencyBlockerMs", "webProbe.browserFreezePolicy.responsiveness"),
      eventBlockerCount: requiredPolicyPositiveNumber(responsiveness, "eventBlockerCount", "webProbe.browserFreezePolicy.responsiveness"),
    },
    cdp: {
      metricsTimeoutBlockerCount: requiredPolicyPositiveNumber(cdp, "metricsTimeoutBlockerCount", "webProbe.browserFreezePolicy.cdp"),
    },
    kill: {
      enabled: requiredPolicyBoolean(kill, "enabled", "webProbe.browserFreezePolicy.kill"),
      gracefulSignal: requiredPolicySignal(kill, "gracefulSignal", "webProbe.browserFreezePolicy.kill", "SIGTERM"),
      forceSignal: requiredPolicySignal(kill, "forceSignal", "webProbe.browserFreezePolicy.kill", "SIGKILL"),
      graceMs: requiredPolicyIntegerInRange(kill, "graceMs", "webProbe.browserFreezePolicy.kill", 1, 120000),
      pollIntervalMs: requiredPolicyIntegerInRange(kill, "pollIntervalMs", "webProbe.browserFreezePolicy.kill", 1, 10000),
      exitCode: requiredPolicyIntegerInRange(kill, "exitCode", "webProbe.browserFreezePolicy.kill", 1, 125),
    },
    source: "yaml-env",
    valuesRedacted: true,
  };
}

function requiredPolicyRecord(raw, key, pathLabel) {
  const value = raw?.[key];
  if (!value || typeof value !== "object" || Array.isArray(value)) {
    throw new Error("UNIDESK_WEB_OBSERVE_BROWSER_FREEZE_POLICY_JSON requires object " + pathLabel + "." + key);
  }
  return value;
}

function requiredPolicyBoolean(raw, key, pathLabel) {
  const value = raw?.[key];
  if (typeof value !== "boolean") {
    throw new Error("UNIDESK_WEB_OBSERVE_BROWSER_FREEZE_POLICY_JSON requires boolean " + pathLabel + "." + key);
  }
  return value;
}

function requiredPolicyPositiveNumber(raw, key, pathLabel) {
  const value = Number(raw?.[key]);
  if (!Number.isFinite(value) || value <= 0) {
    throw new Error("UNIDESK_WEB_OBSERVE_BROWSER_FREEZE_POLICY_JSON requires positive number " + pathLabel + "." + key);
  }
  return value;
}

function requiredPolicyIntegerInRange(raw, key, pathLabel, min, max) {
  const value = Number(raw?.[key]);
  if (!Number.isInteger(value) || value < min || value > max) {
    throw new Error("UNIDESK_WEB_OBSERVE_BROWSER_FREEZE_POLICY_JSON requires integer " + pathLabel + "." + key + " between " + min + " and " + max);
  }
  return value;
}

function requiredPolicySignal(raw, key, pathLabel, expected) {
  const value = String(raw?.[key] || "");
  if (value !== expected) {
    throw new Error("UNIDESK_WEB_OBSERVE_BROWSER_FREEZE_POLICY_JSON requires " + pathLabel + "." + key + "=" + expected);
  }
  return value;
}

function parseProjectManagementConfig(value) {
  if (!value || value === "null") {
    return {
      enabled: false,
      targetPaths: [],
      readinessSelectors: [],
      naturalApiPathPrefixes: [],
      commandAllowlist: [],
      launchRoute: "",
      slowApiBudgetMs: 0,
      source: "yaml-env",
      valuesRedacted: true
    };
  }
  const raw = (() => {
    try { return JSON.parse(value); } catch (error) { throw new Error("UNIDESK_WEB_OBSERVE_PROJECT_MANAGEMENT_JSON is invalid JSON: " + (error instanceof Error ? error.message : String(error))); }
  })();
  if (raw?.enabled !== true && raw?.enabled !== false) throw new Error("UNIDESK_WEB_OBSERVE_PROJECT_MANAGEMENT_JSON requires boolean enabled");
  if (raw.enabled !== true) return { enabled: false, targetPaths: [], readinessSelectors: [], naturalApiPathPrefixes: [], commandAllowlist: [], launchRoute: "", slowApiBudgetMs: 0, source: "yaml-env", valuesRedacted: true };
  const stringList = (key) => {
    const list = raw?.[key];
    if (!Array.isArray(list) || list.some((item) => typeof item !== "string" || item.length === 0)) throw new Error("UNIDESK_WEB_OBSERVE_PROJECT_MANAGEMENT_JSON requires string[] " + key + "; configure config/hwlab-node-lanes.yaml webProbe.projectManagement");
    return list;
  };
  const slowApiBudgetMs = Number(raw?.slowApiBudgetMs);
  if (!Number.isFinite(slowApiBudgetMs) || slowApiBudgetMs <= 0) throw new Error("UNIDESK_WEB_OBSERVE_PROJECT_MANAGEMENT_JSON requires positive slowApiBudgetMs");
  const launchRoute = String(raw.launchRoute || "");
  if (!launchRoute.startsWith("/")) throw new Error("UNIDESK_WEB_OBSERVE_PROJECT_MANAGEMENT_JSON launchRoute must be an absolute path");
  return {
    enabled: true,
    targetPaths: stringList("targetPaths"),
    readinessSelectors: stringList("readinessSelectors"),
    naturalApiPathPrefixes: stringList("naturalApiPathPrefixes"),
    commandAllowlist: stringList("commandAllowlist"),
    launchRoute,
    slowApiBudgetMs,
    source: "yaml-env",
    valuesRedacted: true
  };
}

async function readJsonl(file, options = {}) {
  const tailLimit = Number.isFinite(Number(options.tail)) && Number(options.tail) > 0 ? Math.floor(Number(options.tail)) : 0;
  if (tailLimit > 0) return readJsonlTail(file, tailLimit, options);
  const rows = [];
  try {
    const input = createReadStream(file, { encoding: "utf8" });
    const lines = createInterface({ input, crlfDelay: Infinity });
    let lineNo = 0;
    for await (const rawLine of lines) {
      lineNo += 1;
      const line = String(rawLine || "").trim();
      if (!line) continue;
      try {
        const parsed = JSON.parse(line);
        rows.push(typeof options.compact === "function" ? options.compact(parsed) : parsed);
      } catch (error) {
        const item = { parseError: true, lineNo, rawHash: sha256(line), errorMessage: limitText(error && error.message ? error.message : String(error), 240) };
        rows.push(item);
        if (jsonlReadIssues.length < 50) jsonlReadIssues.push({ file: path.basename(file), kind: "parse-error", lineNo, rawHash: item.rawHash, errorMessage: item.errorMessage });
      }
    }
    return rows;
  } catch (error) {
    if (error && error.code === "ENOENT") return [];
    if (jsonlReadIssues.length < 50) jsonlReadIssues.push({ file: path.basename(file), kind: "read-error", code: error && error.code ? String(error.code) : null, errorMessage: limitText(error && error.message ? error.message : String(error), 240) });
    return [];
  }
}

async function readJsonlTail(file, limit, options = {}) {
  try {
    const lines = await readTailLines(file, limit);
    const rows = [];
    let lineNo = 0;
    for (const rawLine of lines) {
      lineNo += 1;
      const line = String(rawLine || "").trim();
      if (!line) continue;
      try {
        const parsed = JSON.parse(line);
        rows.push(typeof options.compact === "function" ? options.compact(parsed) : parsed);
      } catch (error) {
        const item = { parseError: true, lineNo, tail: true, rawHash: sha256(line), errorMessage: limitText(error && error.message ? error.message : String(error), 240) };
        rows.push(item);
        if (jsonlReadIssues.length < 50) jsonlReadIssues.push({ file: path.basename(file), kind: "parse-error", lineNo, tail: true, rawHash: item.rawHash, errorMessage: item.errorMessage });
      }
    }
    return rows;
  } catch (error) {
    if (error && error.code === "ENOENT") return [];
    if (jsonlReadIssues.length < 50) jsonlReadIssues.push({ file: path.basename(file), kind: "read-error", tail: true, code: error && error.code ? String(error.code) : null, errorMessage: limitText(error && error.message ? error.message : String(error), 240) });
    return [];
  }
}

async function readTailLines(file, limit) {
  const info = await stat(file);
  if (!info.size || limit <= 0) return [];
  const chunkSize = 64 * 1024;
  const maxBytes = Math.max(32 * 1024 * 1024, Math.min(256 * 1024 * 1024, limit * 512 * 1024));
  const chunks = [];
  let position = info.size;
  let readBytes = 0;
  let newlineCount = 0;
  while (position > 0 && newlineCount <= limit && readBytes < maxBytes) {
    const readSize = Math.min(chunkSize, position, maxBytes - readBytes);
    position -= readSize;
    const chunk = await readFileSlice(file, position, readSize);
    chunks.unshift(chunk);
    readBytes += chunk.length;
    for (let index = 0; index < chunk.length; index += 1) {
      if (chunk[index] === 10) newlineCount += 1;
    }
  }
  if (position > 0 && newlineCount <= limit && jsonlReadIssues.length < 50) {
    jsonlReadIssues.push({ file: path.basename(file), kind: "tail-scan-truncated", limit, readBytes, fileBytes: info.size });
  }
  const text = Buffer.concat(chunks).toString("utf8");
  let lines = text.split(/\r?\n/u);
  if (lines.length > 0 && lines[lines.length - 1] === "") lines.pop();
  if (position > 0 && lines.length > 0) lines.shift();
  return lines.slice(-limit);
}

async function readFileSlice(file, start, length) {
  const chunks = [];
  await new Promise((resolve, reject) => {
    const stream = createReadStream(file, { start, end: start + length - 1 });
    stream.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
    stream.on("error", reject);
    stream.on("end", resolve);
  });
  return Buffer.concat(chunks);
}

function sampleTimeWindow(samples, paddingMs) {
  const times = samples
    .map((item) => Date.parse(String(item && item.ts || "")))
    .filter((value) => Number.isFinite(value));
  if (times.length === 0) return { startMs: null, endMs: null, startAt: null, endAt: null, paddingMs };
  const startMs = Math.max(0, Math.min(...times) - Math.max(0, paddingMs || 0));
  const endMs = Math.max(...times) + Math.max(0, paddingMs || 0);
  return { startMs, endMs, startAt: new Date(startMs).toISOString(), endAt: new Date(endMs).toISOString(), paddingMs };
}

function filterRowsByTimeWindow(rows, window) {
  if (!window || !Number.isFinite(window.startMs) || !Number.isFinite(window.endMs)) return rows;
  return rows.filter((item) => {
    const value = item && (item.ts || item.observedAt || item.startedAt || item.finishedAt || item.createdAt || item.updatedAt);
    const ms = Date.parse(String(value || ""));
    if (!Number.isFinite(ms)) return true;
    return ms >= window.startMs && ms <= window.endMs;
  });
}

function analysisFocusFromControl(control) {
  const completedNewSessions = (Array.isArray(control) ? control : [])
    .filter((item) => item?.type === "newSession" && item?.phase === "completed" && Number.isFinite(Date.parse(String(item.ts || ""))))
    .sort((a, b) => Date.parse(String(a.ts || "")) - Date.parse(String(b.ts || "")));
  const latest = completedNewSessions.at(-1) ?? null;
  if (!latest) return { mode: "all", reason: "no-new-session-command", startAt: null, startMs: null, commandId: null, valuesRedacted: true };
  const startMs = Date.parse(String(latest.ts));
  return {
    mode: "after-new-session",
    reason: "latest-completed-new-session",
    startAt: new Date(startMs).toISOString(),
    startMs,
    commandId: latest.commandId ?? null,
    valuesRedacted: true
  };
}

function applyAnalysisFocus(rows, focus, graceMs = 0) {
  if (!focus || !Number.isFinite(focus.startMs)) return rows;
  const minMs = focus.startMs - Math.max(0, Number(graceMs) || 0);
  return (Array.isArray(rows) ? rows : []).filter((item) => {
    const value = item && (item.ts || item.observedAt || item.startedAt || item.finishedAt || item.createdAt || item.updatedAt);
    const ms = Date.parse(String(value || ""));
    return Number.isFinite(ms) ? ms >= minMs : true;
  });
}

function analysisControlWindow(sampleWindow, focus, graceMs = 0) {
  if (!sampleWindow || !Number.isFinite(sampleWindow.endMs)) return sampleWindow;
  if (!focus || !Number.isFinite(focus.startMs)) return sampleWindow;
  const startMs = Math.max(0, Math.min(Number(sampleWindow.startMs ?? focus.startMs), focus.startMs - Math.max(0, Number(graceMs) || 0)));
  return {
    ...sampleWindow,
    startMs,
    startAt: new Date(startMs).toISOString()
  };
}

function compactSampleForAnalysis(sample) {
  if (!sample || typeof sample !== "object") return sample;
  return {
    seq: sample.seq ?? null,
    ts: sample.ts ?? null,
    reason: sample.reason ?? null,
    sampleGroupSeq: sample.sampleGroupSeq ?? null,
    pageId: sample.pageId ?? null,
    pageRole: sample.pageRole ?? null,
    commandId: sample.commandId ?? null,
    observerInitiated: sample.observerInitiated ?? null,
    url: sample.url ?? null,
    path: sample.path ?? null,
    title: sample.title ?? null,
    routeSessionId: sample.routeSessionId ?? null,
    activeSessionId: sample.activeSessionId ?? null,
    messages: compactDomItems(sample.messages),
    traceRows: compactDomItems(sample.traceRows),
    loadings: compactLoadingItems(sample.loadings),
    sessionRail: compactSessionRail(sample.sessionRail),
    turns: compactDomItems(sample.turns),
    diagnostics: compactDomItems(sample.diagnostics),
    composer: compactComposer(sample.composer),
    projectManagement: compactProjectManagementSample(sample.projectManagement),
    pageProvenance: compactSamplePageProvenance(sample.pageProvenance),
    performance: compactPerformanceItems(sample.performance)
  };
}

function compactProjectManagementSample(value) {
  if (!value || typeof value !== "object") return null;
  return {
    pageKind: value.pageKind ?? null,
    configuredPath: value.configuredPath === true,
    rootVisible: value.rootVisible === true,
    mdtodoVisible: value.mdtodoVisible === true,
    sourceCount: value.sourceCount ?? null,
    fileCount: value.fileCount ?? null,
    taskCount: value.taskCount ?? null,
    taskRefMissingCount: value.taskRefMissingCount ?? null,
    selectedSourceId: value.selectedSourceId ?? null,
    selectedFileRef: value.selectedFileRef ?? null,
    selectedTaskRef: value.selectedTaskRef ?? null,
    selectedTaskStatus: value.selectedTaskStatus ?? null,
    sourceSelectVisible: value.sourceSelectVisible === true,
    fileSelectVisible: value.fileSelectVisible === true,
    sourceConfigVisible: value.sourceConfigVisible === true,
    taskEditorVisible: value.taskEditorVisible === true,
    taskBodyVisible: value.taskBodyVisible === true,
    taskBody: value.taskBody ?? null,
    reportLinkCount: value.reportLinkCount ?? 0,
    reportPreviewVisible: value.reportPreviewVisible === true,
    reportPreview: value.reportPreview ?? null,
    reportFullscreenVisible: value.reportFullscreenVisible === true,
    newTaskDraftVisible: value.newTaskDraftVisible === true,
    taskStatusCounts: value.taskStatusCounts && typeof value.taskStatusCounts === "object" ? value.taskStatusCounts : {},
    launchButtonVisible: value.launchButtonVisible === true,
    launchButtonEnabled: value.launchButtonEnabled === true,
    launchButtonText: value.launchButtonText ?? null,
    blockerCount: value.blockerCount ?? 0,
    blockers: Array.isArray(value.blockers) ? value.blockers.slice(0, 6) : [],
    paneGaps: Array.isArray(value.paneGaps) ? value.paneGaps.slice(0, 8).map((item) => ({
      name: item?.name ?? null,
      visible: item?.visible === true,
      widthPx: item?.widthPx ?? null,
      heightPx: item?.heightPx ?? null,
      bottomGapPx: item?.bottomGapPx ?? null,
      bottomGapRatio: item?.bottomGapRatio ?? null,
      contentNodeCount: item?.contentNodeCount ?? null,
      valuesRedacted: true
    })) : [],
    workbenchLinkCount: value.workbenchLinkCount ?? 0,
    valuesRedacted: true
  };
}

function compactSessionRail(value) {
  if (!value || typeof value !== "object") return null;
  const items = Array.isArray(value.items) ? value.items.slice(0, 80).map((item) => ({
    index: item?.index ?? null,
    tag: item?.tag ?? null,
    testId: item?.testId ?? null,
    role: item?.role ?? null,
    active: item?.active === true,
    status: item?.status ?? null,
    dataStatus: item?.dataStatus ?? null,
    running: item?.running === true,
    dataRunning: item?.dataRunning ?? null,
    ariaBusy: item?.ariaBusy ?? null,
    sessionIdPrefix: item?.sessionIdPrefix ?? (item?.sessionId ? String(item.sessionId).slice(0, 12) : null),
    fallbackTitle: item?.fallbackTitle === true,
    titlePreview: limitText(String(item?.titlePreview || item?.titleText || ""), 180),
    titleHash: item?.titleHash ?? sha256(String(item?.titlePreview || item?.titleText || "")),
    titleBytes: item?.titleBytes ?? null,
  })) : [];
  const fallbackItems = Array.isArray(value.fallbackItems)
    ? value.fallbackItems.slice(0, 20).map((item) => ({
      index: item?.index ?? null,
      active: item?.active === true,
      sessionIdPrefix: item?.sessionIdPrefix ?? (item?.sessionId ? String(item.sessionId).slice(0, 12) : null),
      titlePreview: limitText(String(item?.titlePreview || item?.titleText || ""), 180),
      titleHash: item?.titleHash ?? sha256(String(item?.titlePreview || item?.titleText || "")),
    }))
    : items.filter((item) => item.fallbackTitle).slice(0, 20);
  const visibleCount = Number(value.visibleCount ?? items.length);
  const fallbackTitleCount = Number(value.fallbackTitleCount ?? fallbackItems.length);
  return {
    visibleCount: Number.isFinite(visibleCount) ? visibleCount : items.length,
    fallbackTitleCount: Number.isFinite(fallbackTitleCount) ? fallbackTitleCount : fallbackItems.length,
    fallbackTitleRatio: Number.isFinite(Number(value.fallbackTitleRatio)) ? Number(value.fallbackTitleRatio) : (items.length > 0 ? Number((fallbackItems.length / items.length).toFixed(4)) : 0),
    activeItem: items.find((item) => item.active) || null,
    items,
    fallbackItems,
    valuesRedacted: true
  };
}

function compactComposer(value) {
  if (!value || typeof value !== "object") return null;
  return {
    inputPresent: value.inputPresent === true,
    inputDisabled: value.inputDisabled === true,
    warningPresent: value.warningPresent === true,
    submitPresent: value.submitPresent === true,
    submitDisabled: value.submitDisabled === true,
    submitAction: value.submitAction ?? null,
    activeStatus: value.activeStatus ?? null,
    valuesRedacted: true
  };
}

function compactLoadingItems(items) {
  if (!Array.isArray(items)) return [];
  return items.map((item) => {
    if (!item || typeof item !== "object") return item;
    const rawText = String(item.text ?? item.textPreview ?? "");
    return {
      index: item.index ?? null,
      tag: item.tag ?? null,
      testId: item.testId ?? null,
      role: item.role ?? null,
      ownerKind: item.ownerKind ?? null,
      ownerKey: item.ownerKey ?? null,
      ownerLabel: item.ownerLabel ?? null,
      owner: item.owner && typeof item.owner === "object" ? {
        tag: item.owner.tag ?? null,
        testId: item.owner.testId ?? null,
        role: item.owner.role ?? null,
        id: item.owner.id ?? null,
        className: item.owner.className ?? null,
        status: item.owner.status ?? null,
        sessionId: item.owner.sessionId ?? null,
        messageId: item.owner.messageId ?? null,
        traceId: item.owner.traceId ?? null,
        ariaLabel: item.owner.ariaLabel ?? null,
      } : null,
      text: limitText(rawText, 400),
      textPreview: limitText(String(item.textPreview ?? rawText), 240),
      textHash: item.textHash ?? sha256(rawText),
      textBytes: item.textBytes ?? Buffer.byteLength(rawText),
      ownerTextHash: item.ownerTextHash ?? null,
      ownerTextPreview: item.ownerTextPreview ? limitText(item.ownerTextPreview, 240) : null,
    };
  });
}

function compactDomItems(items) {
  if (!Array.isArray(items)) return [];
  return items.map(compactDomItem);
}

function compactDomItem(item) {
  if (!item || typeof item !== "object") return item;
  const rawText = String(item.text ?? item.textPreview ?? "");
  const preview = String(item.textPreview ?? limitText(rawText, 240));
  const hasBodyTextPresent = Object.prototype.hasOwnProperty.call(item, "bodyTextPresent");
  const hasFinalResponsePresent = Object.prototype.hasOwnProperty.call(item, "finalResponsePresent");
  return {
    index: item.index ?? null,
    tag: item.tag ?? null,
    testId: item.testId ?? null,
    role: item.role ?? null,
    dataRole: item.dataRole ?? null,
    status: item.status ?? null,
    sessionId: item.sessionId ?? null,
    messageId: item.messageId ?? null,
    traceId: item.traceId ?? null,
    turnId: item.turnId ?? null,
    projectedSeq: Number.isFinite(Number(item.projectedSeq)) ? Number(item.projectedSeq) : null,
    sourceSeq: Number.isFinite(Number(item.sourceSeq)) ? Number(item.sourceSeq) : null,
    eventSeq: Number.isFinite(Number(item.eventSeq)) ? Number(item.eventSeq) : null,
    eventTimestamp: item.eventTimestamp ?? null,
    eventTimeText: item.eventTimeText ?? null,
    eventKind: item.eventKind ?? null,
    durationText: item.durationText ?? null,
    activityText: item.activityText ?? null,
    bodyTextSource: item.bodyTextSource ?? null,
    bodyTextCandidateCount: Number.isFinite(Number(item.bodyTextCandidateCount)) ? Number(item.bodyTextCandidateCount) : null,
    bodyTextPresent: hasBodyTextPresent ? item.bodyTextPresent === true : null,
    bodyTextPreview: item.bodyTextPreview ? limitText(item.bodyTextPreview, 600) : undefined,
    bodyTextHash: item.bodyTextHash ?? null,
    bodyTextBytes: Number.isFinite(Number(item.bodyTextBytes)) ? Number(item.bodyTextBytes) : null,
    finalResponsePresent: hasFinalResponsePresent ? item.finalResponsePresent === true : null,
    finalResponseTextSource: item.finalResponseTextSource ?? null,
    finalResponseCandidateCount: Number.isFinite(Number(item.finalResponseCandidateCount)) ? Number(item.finalResponseCandidateCount) : null,
    finalResponseTextPreview: item.finalResponseTextPreview ? limitText(item.finalResponseTextPreview, 600) : undefined,
    finalResponseTextHash: item.finalResponseTextHash ?? null,
    finalResponseTextBytes: Number.isFinite(Number(item.finalResponseTextBytes)) ? Number(item.finalResponseTextBytes) : null,
    className: item.className ?? null,
    diagnosticCode: item.diagnosticCode ?? null,
    source: item.source ?? null,
    sources: Array.isArray(item.sources) ? item.sources.slice(0, 8) : undefined,
    text: limitText(rawText, 4000),
    textPreview: limitText(preview, 600),
    textHash: item.textHash ?? sha256(rawText),
    textBytes: item.textBytes ?? Buffer.byteLength(rawText)
  };
}

function compactPerformanceItems(items) {
  if (!Array.isArray(items)) return [];
  return items.map((item) => ({
    name: item?.name ?? null,
    initiatorType: item?.initiatorType ?? null,
    startTime: item?.startTime ?? null,
    duration: item?.duration ?? null,
    workerStart: item?.workerStart ?? null,
    redirectStart: item?.redirectStart ?? null,
    redirectEnd: item?.redirectEnd ?? null,
    fetchStart: item?.fetchStart ?? null,
    domainLookupStart: item?.domainLookupStart ?? null,
    domainLookupEnd: item?.domainLookupEnd ?? null,
    connectStart: item?.connectStart ?? null,
    connectEnd: item?.connectEnd ?? null,
    secureConnectionStart: item?.secureConnectionStart ?? null,
    requestStart: item?.requestStart ?? null,
    responseStart: item?.responseStart ?? null,
    responseEnd: item?.responseEnd ?? null,
    transferSize: item?.transferSize ?? null,
    encodedBodySize: item?.encodedBodySize ?? null,
    decodedBodySize: item?.decodedBodySize ?? null,
    nextHopProtocol: item?.nextHopProtocol ?? null,
    responseStatus: Number.isFinite(Number(item?.responseStatus)) ? Number(item.responseStatus) : null
  }));
}

function compactLoadingMetricsForOutput(value) {
  if (!value || typeof value !== "object") return null;
  return {
    summary: value.summary ?? null,
    longestSegments: Array.isArray(value.segments) ? value.segments.slice(0, 8) : [],
    owners: Array.isArray(value.owners) ? value.owners.slice(0, 8) : [],
    timeline: Array.isArray(value.timeline) ? value.timeline.slice(-12) : [],
    valuesRedacted: true
  };
}

function compactSessionRailTitleMetricsForOutput(value) {
  if (!value || typeof value !== "object") return null;
  return {
    summary: value.summary ?? null,
    samples: Array.isArray(value.samples) ? value.samples.slice(0, 12) : [],
    examples: Array.isArray(value.examples) ? value.examples.slice(0, 12) : [],
    timeline: Array.isArray(value.timeline) ? value.timeline.slice(-12) : [],
    valuesRedacted: true
  };
}

function compactWorkbenchTurnStateTriadForOutput(value) {
  if (!value || typeof value !== "object") return null;
  return {
    summary: value.summary ?? null,
    drilldown: value.drilldown ?? null,
    invalidFullTriads: Array.isArray(value.invalidFullTriads) ? value.invalidFullTriads.slice(0, 8) : [],
    cardFinalResponseMismatches: Array.isArray(value.cardFinalResponseMismatches) ? value.cardFinalResponseMismatches.slice(0, 8) : [],
    collectorMissingRows: Array.isArray(value.collectorMissingRows) ? value.collectorMissingRows.slice(0, 8) : [],
    valuesRedacted: true
  };
}

function compactSamplePageProvenance(value) {
  if (!value || typeof value !== "object") return null;
  return {
    pageLoadSeq: value.pageLoadSeq ?? null,
    reason: value.reason ?? null,
    observedAt: value.observedAt ?? null,
    urlPath: value.urlPath ?? null,
    documentReadyState: value.documentReadyState ?? null,
    timeOrigin: value.timeOrigin ?? null,
    httpStatus: value.httpStatus ?? null,
    assetFingerprint: value.assetFingerprint ?? null,
    scriptCount: value.scriptCount ?? null,
    stylesheetCount: value.stylesheetCount ?? null,
    metaCount: value.metaCount ?? null,
    scripts: Array.isArray(value.scripts) ? value.scripts.slice(0, 20) : [],
    stylesheets: Array.isArray(value.stylesheets) ? value.stylesheets.slice(0, 20) : [],
    error: value.error ?? null,
    valuesRedacted: true
  };
}

function summarizeCommandFailures(control) {
  return control.filter((item) => item?.phase === "failed").map((item) => {
    const detail = item?.detail && typeof item.detail === "object" ? item.detail : {};
    const error = detail?.error && typeof detail.error === "object" ? detail.error : detail;
    return {
      ts: item.ts ?? null,
      commandId: item.commandId ?? null,
      type: item.type ?? item.input?.type ?? null,
      phase: "failed",
      status: "failed",
      source: item.source ?? null,
      durationMs: detail.durationMs ?? null,
      beforePath: urlPath(detail.beforeUrl || item.beforeUrl),
      afterPath: urlPath(detail.afterUrl || item.afterUrl),
      name: error?.name ?? null,
      message: limitText(error?.message ?? detail?.message ?? "", 240),
      failureKind: error?.failureKind ?? detail?.failureKind ?? null,
      failedReason: limitText(error?.message ?? detail?.message ?? error?.failureKind ?? detail?.failureKind ?? "observer-command-failed", 240),
      resultOk: false,
      artifactBucket: "failed",
      artifactRef: item.commandId ? "commands/failed/" + item.commandId + ".json" : null,
      failedAt: item.ts ?? null,
      failureSampleOk: detail?.failureSample?.ok === true,
      sampleSeq: detail?.failureSample?.sampleSeq ?? null,
      valuesRedacted: true
    };
  });
}
`;
}
