#![recursion_limit = "512"]

use chrono::{DateTime, SecondsFormat, Utc};
use postgres::{Client, NoTls};
use serde_json::{json, Map, Value};
use std::collections::{BTreeSet, HashSet, VecDeque};
use std::env;
use std::error::Error;
use std::fs::{create_dir_all, OpenOptions};
use std::io::{Read, Write};
use std::net::TcpStream;
use std::path::Path;
use std::sync::{Arc, Mutex};
use tiny_http::{Header, Method, Request, Response, Server, StatusCode};

const DEFAULT_QUEUE_ID: &str = "default";
const MAX_BODY_BYTES: usize = 512 * 1024;
const MAX_LIST_LIMIT: i64 = 200;
const MAX_OUTPUT_PAGE_LIMIT: usize = 500;
const MAX_PREVIEW_CHARS: usize = 6000;
const WORKDIR_MAX_CHARS: usize = 512;
const SCHEDULER_HEARTBEAT_STALE_MS: i64 = 5 * 60 * 1000;
const CODEX_STATS_TIME_ZONE: &str = "Asia/Shanghai";
const DEEPSEEK_CHAT_MODEL: &str = "deepseek-chat";
const MINIMAX_M27_MODEL: &str = "minimax-m2.7";

#[derive(Clone)]
struct Config {
    host: String,
    port: u16,
    database_url: String,
    log_file: String,
    deploy_service_id: String,
    deploy_repo: String,
    deploy_commit: String,
    deploy_requested_commit: String,
    mgr_pool_max: i64,
    trace_pool_max: i64,
    default_provider_id: String,
    default_workdir: String,
    remote_default_workdir: String,
    default_model: String,
    code_models: Vec<String>,
    default_max_attempts: i64,
    default_reasoning_effort: Option<String>,
    model_reasoning_efforts: Value,
}

#[derive(Clone)]
struct AppState {
    config: Config,
    started_at: String,
    logs: Arc<Mutex<VecDeque<Value>>>,
    schema_ready: Arc<Mutex<bool>>,
    schema_last_error: Arc<Mutex<Option<Value>>>,
    last_database_error: Arc<Mutex<Option<String>>>,
}

#[derive(Clone, Debug)]
struct TaskMeta {
    id: String,
    queue_id: String,
    status: String,
    provider_id: String,
    execution_mode: String,
    model: String,
    cwd: String,
    prompt: String,
    base_prompt: String,
    reference_task_ids: Value,
    reference_injection: Option<Value>,
    reasoning_effort: Option<String>,
    max_attempts: i64,
    current_attempt: i64,
    current_mode: Option<String>,
    codex_thread_id: Option<String>,
    active_turn_id: Option<String>,
    created_at: String,
    updated_at: String,
    started_at: Option<String>,
    finished_at: Option<String>,
    read_at: Option<String>,
    last_error: Option<String>,
    last_judge: Option<Value>,
    output_count: i64,
    event_count: i64,
    attempt_count: i64,
    last_output_seq: i64,
    task_json: Option<Value>,
}

#[derive(Clone, Debug)]
struct DailyTaskStatsRow {
    date: String,
    executed_tasks: i64,
    completed_tasks: i64,
    retry_attempts: i64,
    succeeded_tasks: i64,
    failed_tasks: i64,
    canceled_tasks: i64,
    total_duration_ms: i64,
    duration_samples: i64,
}

#[derive(Clone, Debug)]
struct RequestUrl {
    path: String,
    query: Vec<(String, String)>,
}

fn now_iso() -> String {
    Utc::now().to_rfc3339_opts(SecondsFormat::Millis, true)
}

fn env_string(name: &str, fallback: &str) -> String {
    env::var(name).ok().filter(|value| !value.is_empty()).unwrap_or_else(|| fallback.to_string())
}

fn env_number(name: &str, fallback: i64) -> i64 {
    env::var(name)
        .ok()
        .and_then(|value| value.parse::<i64>().ok())
        .filter(|value| *value > 0)
        .unwrap_or(fallback)
}

fn normalize_code_model(value: &str) -> String {
    let raw = value.trim();
    if raw.is_empty() {
        return raw.to_string();
    }
    let lower = raw.to_ascii_lowercase();
    let leaf = lower.rsplit('/').next().unwrap_or(&lower);
    if leaf == "m2.7" || leaf == "minimax-m2.7" {
        return MINIMAX_M27_MODEL.to_string();
    }
    if leaf == "deepseek" || leaf == "deepseek-chat" {
        return DEEPSEEK_CHAT_MODEL.to_string();
    }
    raw.to_string()
}

fn code_agent_port(model: &str) -> &'static str {
    let normalized = normalize_code_model(model);
    if normalized == MINIMAX_M27_MODEL || normalized == DEEPSEEK_CHAT_MODEL {
        "opencode"
    } else {
        "codex"
    }
}

fn code_agent_port_info(kind: &str) -> Value {
    if kind == "opencode" {
        json!({
            "kind": "opencode",
            "protocol": "opencode-run-json-events",
            "sessionResume": "opencode --session with persisted XDG storage and stale-session recovery",
            "tracePort": "opencode-json-event"
        })
    } else {
        json!({
            "kind": "codex",
            "protocol": "codex-app-server-jsonrpc-stdio",
            "sessionResume": "thread/resume",
            "tracePort": "codex-transcript"
        })
    }
}

fn execution_mode_info(mode: &str) -> Value {
    if mode == "windows-native" {
        json!({
            "kind": "windows-native",
            "label": "Windows native Codex",
            "description": "Run Codex on the provider Windows host while the execution container relays stdio.",
            "codexRunsInContainer": false,
            "requiresProvider": true,
            "requiresWindowsCwd": true
        })
    } else {
        json!({
            "kind": "default",
            "label": "Default Codex runtime",
            "description": "Use the Code Queue node Codex runtime or the provider execution container.",
            "codexRunsInContainer": true,
            "requiresProvider": false,
            "requiresWindowsCwd": false
        })
    }
}

fn parse_model_reasoning_efforts(raw: &str) -> Value {
    let mut map = Map::new();
    map.insert("gpt-5.5".to_string(), json!("xhigh"));
    for item in raw.split([',', ';']) {
        let trimmed = item.trim();
        if trimmed.is_empty() {
            continue;
        }
        if let Some((model, effort)) = trimmed.split_once('=') {
            let model = model.trim().to_ascii_lowercase();
            let effort = effort.trim();
            if !model.is_empty() && !effort.is_empty() {
                map.insert(model, json!(effort));
            }
        }
    }
    Value::Object(map)
}

fn config_from_env() -> Result<Config, String> {
    let database_url = env_string("DATABASE_URL", "");
    if database_url.is_empty() {
        return Err("DATABASE_URL is required".to_string());
    }
    let default_model = normalize_code_model(&env_string("CODE_QUEUE_DEFAULT_MODEL", "gpt-5.5"));
    let model_source = env_string("CODE_QUEUE_MODELS", "gpt-5.5,gpt-5.4-mini,gpt-5.4,deepseek-chat,minimax-m2.7");
    let mut code_models = vec![default_model.clone()];
    for item in model_source.split(',') {
        let model = normalize_code_model(item);
        if !model.is_empty() && !code_models.iter().any(|existing| existing == &model) {
            code_models.push(model);
        }
    }
    Ok(Config {
        host: env_string("HOST", "0.0.0.0"),
        port: env_number("PORT", 4278).clamp(1, 65535) as u16,
        database_url,
        log_file: env_string("LOG_FILE", "/var/log/unidesk/code-queue-mgr.jsonl"),
        deploy_service_id: env_string("UNIDESK_CODE_QUEUE_MGR_DEPLOY_SERVICE_ID", "code-queue-mgr"),
        deploy_repo: env_string("UNIDESK_CODE_QUEUE_MGR_DEPLOY_REPO", ""),
        deploy_commit: env_string("UNIDESK_CODE_QUEUE_MGR_DEPLOY_COMMIT", ""),
        deploy_requested_commit: env_string("UNIDESK_CODE_QUEUE_MGR_DEPLOY_REQUESTED_COMMIT", ""),
        mgr_pool_max: env_number("CODE_QUEUE_MGR_DATABASE_POOL_MAX", 2).clamp(1, 2),
        trace_pool_max: env_number("CODE_QUEUE_TRACE_DATABASE_POOL_MAX", 1).clamp(1, 2),
        default_provider_id: env_string("CODE_QUEUE_MAIN_PROVIDER_ID", "D601"),
        default_workdir: env_string("CODE_QUEUE_WORKDIR", "/workspace"),
        remote_default_workdir: env_string("CODE_QUEUE_REMOTE_WORKDIR", "/home/ubuntu"),
        default_model,
        code_models,
        default_max_attempts: env_number("CODE_QUEUE_MAX_ATTEMPTS", 99).clamp(1, 99),
        default_reasoning_effort: env::var("CODE_QUEUE_DEFAULT_REASONING_EFFORT").ok().filter(|value| !value.trim().is_empty()),
        model_reasoning_efforts: parse_model_reasoning_efforts(&env_string("CODE_QUEUE_MODEL_REASONING_EFFORTS", "")),
    })
}

fn with_lock<T, F>(mutex: &Mutex<T>, f: F)
where
    F: FnOnce(&mut T),
{
    if let Ok(mut guard) = mutex.lock() {
        f(&mut guard);
    }
}

fn set_schema_ready(state: &AppState, ready: bool, error: Option<Value>) {
    with_lock(&state.schema_ready, |value| *value = ready);
    with_lock(&state.schema_last_error, |value| *value = error.clone());
    if let Some(error) = error {
        with_lock(&state.last_database_error, |value| *value = Some(error.to_string()));
    }
}

fn schema_ready(state: &AppState) -> bool {
    state.schema_ready.lock().map(|value| *value).unwrap_or(false)
}

fn schema_last_error(state: &AppState) -> Option<Value> {
    state.schema_last_error.lock().ok().and_then(|value| value.clone())
}

fn last_database_error(state: &AppState) -> Option<String> {
    state.last_database_error.lock().ok().and_then(|value| value.clone())
}

fn log_event(state: &AppState, level: &str, event: &str, mut detail: Value) {
    let mut record = Map::new();
    record.insert("at".to_string(), json!(now_iso()));
    record.insert("service".to_string(), json!("code-queue-mgr"));
    record.insert("runtime".to_string(), json!("rust"));
    record.insert("level".to_string(), json!(level));
    record.insert("event".to_string(), json!(event));
    if let Value::Object(detail_map) = &mut detail {
        for (key, value) in std::mem::take(detail_map) {
            record.insert(key, value);
        }
    }
    let value = Value::Object(record);
    with_lock(&state.logs, |logs| {
        logs.push_back(value.clone());
        while logs.len() > 300 {
            logs.pop_front();
        }
    });
    let text = value.to_string();
    if !state.config.log_file.is_empty() {
        if let Some(parent) = Path::new(&state.config.log_file).parent() {
            let _ = create_dir_all(parent);
        }
        if let Ok(mut file) = OpenOptions::new().create(true).append(true).open(&state.config.log_file) {
            let _ = writeln!(file, "{text}");
        }
    }
    if level == "error" {
        eprintln!("{text}");
    } else {
        println!("{text}");
    }
}

fn db_client(state: &AppState, application_name: &str) -> Result<Client, String> {
    let mut client = Client::connect(&state.config.database_url, NoTls).map_err(|error| error.to_string())?;
    let app = application_name.replace('\'', "");
    let _ = client.batch_execute(&format!(
        "SET application_name = '{}'; SET statement_timeout = '8000ms'; SET lock_timeout = '2000ms'",
        app
    ));
    Ok(client)
}

fn error_detail(error: &(dyn Error + 'static)) -> String {
    let mut parts = vec![error.to_string()];
    let mut source = error.source();
    while let Some(next) = source {
        parts.push(next.to_string());
        source = next.source();
    }
    parts.join(": ")
}

fn ensure_schema(state: &AppState) -> Result<(), String> {
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-schema")?;
    client.batch_execute(
        "
        CREATE TABLE IF NOT EXISTS unidesk_code_queue_tasks (
          id TEXT PRIMARY KEY,
          queue_id TEXT NOT NULL DEFAULT 'default',
          status TEXT NOT NULL,
          provider_id TEXT NOT NULL DEFAULT 'main-server',
          execution_mode TEXT NOT NULL DEFAULT 'default',
          model TEXT NOT NULL,
          cwd TEXT NOT NULL,
          prompt TEXT NOT NULL,
          base_prompt TEXT NOT NULL DEFAULT '',
          reference_task_ids JSONB NOT NULL DEFAULT '[]'::jsonb,
          reference_injection JSONB,
          reasoning_effort TEXT,
          max_attempts INTEGER NOT NULL,
          current_attempt INTEGER NOT NULL DEFAULT 0,
          current_mode TEXT,
          codex_thread_id TEXT,
          active_turn_id TEXT,
          created_at TIMESTAMPTZ NOT NULL,
          updated_at TIMESTAMPTZ NOT NULL,
          started_at TIMESTAMPTZ,
          finished_at TIMESTAMPTZ,
          read_at TIMESTAMPTZ,
          last_error TEXT,
          last_judge JSONB,
          output_count INTEGER NOT NULL DEFAULT 0,
          event_count INTEGER NOT NULL DEFAULT 0,
          attempt_count INTEGER NOT NULL DEFAULT 0,
          last_output_seq BIGINT NOT NULL DEFAULT 0,
          task_json JSONB NOT NULL
        );
        CREATE TABLE IF NOT EXISTS unidesk_code_queue_queues (
          id TEXT PRIMARY KEY,
          name TEXT NOT NULL DEFAULT '',
          created_at TIMESTAMPTZ NOT NULL,
          updated_at TIMESTAMPTZ NOT NULL
        );
        CREATE TABLE IF NOT EXISTS unidesk_code_queue_workdirs (
          provider_id TEXT NOT NULL,
          execution_mode TEXT NOT NULL DEFAULT 'default',
          path TEXT NOT NULL,
          created_at TIMESTAMPTZ NOT NULL,
          updated_at TIMESTAMPTZ NOT NULL,
          PRIMARY KEY (provider_id, execution_mode, path)
        );
        ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS queue_id TEXT NOT NULL DEFAULT 'default';
        ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS provider_id TEXT NOT NULL DEFAULT 'main-server';
        ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS execution_mode TEXT NOT NULL DEFAULT 'default';
        ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS base_prompt TEXT NOT NULL DEFAULT '';
        ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS reference_task_ids JSONB NOT NULL DEFAULT '[]'::jsonb;
        ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS reference_injection JSONB;
        ALTER TABLE unidesk_code_queue_tasks ADD COLUMN IF NOT EXISTS read_at TIMESTAMPTZ;
        ALTER TABLE unidesk_code_queue_queues ADD COLUMN IF NOT EXISTS name TEXT NOT NULL DEFAULT '';
        ALTER TABLE unidesk_code_queue_workdirs ADD COLUMN IF NOT EXISTS execution_mode TEXT NOT NULL DEFAULT 'default';
        CREATE INDEX IF NOT EXISTS idx_code_queue_tasks_list ON unidesk_code_queue_tasks (status, updated_at DESC, id DESC);
        CREATE INDEX IF NOT EXISTS idx_code_queue_tasks_queue_updated ON unidesk_code_queue_tasks (queue_id, updated_at DESC, id DESC);
        ",
    ).map_err(|error| error_detail(&error))?;
    let now = now_iso();
    client
        .execute(
            "
            INSERT INTO unidesk_code_queue_queues (id, name, created_at, updated_at)
            VALUES ($1, $2, $3::text::timestamptz, $3::text::timestamptz)
            ON CONFLICT (id) DO NOTHING
            ",
            &[&DEFAULT_QUEUE_ID.to_string(), &DEFAULT_QUEUE_ID.to_string(), &now],
        )
        .map_err(|error| error_detail(&error))?;
    upsert_default_workdir(&mut client, state, &now)?;
    Ok(())
}

fn ensure_schema_with_retry(state: AppState) {
    for attempt in 1..=12 {
        match ensure_schema(&state) {
            Ok(()) => {
                set_schema_ready(&state, true, None);
                log_event(&state, "info", "schema_ready", json!({ "attempt": attempt }));
                return;
            }
            Err(error) => {
                let detail = json!({ "message": error });
                set_schema_ready(&state, false, Some(detail.clone()));
                log_event(&state, "warn", "schema_retry", json!({ "attempt": attempt, "error": detail }));
                std::thread::sleep(std::time::Duration::from_millis((attempt * 1000).min(10_000)));
            }
        }
    }
}

fn json_response(body: Value, status: u16) -> Response<std::io::Cursor<Vec<u8>>> {
    let mut response = Response::from_string(serde_json::to_string_pretty(&body).unwrap_or_else(|_| "{}".to_string()))
        .with_status_code(StatusCode(status));
    for (name, value) in [
        ("content-type", "application/json; charset=utf-8"),
        ("access-control-allow-origin", "*"),
        ("access-control-allow-methods", "GET,HEAD,POST,PATCH,PUT,DELETE,OPTIONS"),
        ("access-control-allow-headers", "content-type,accept"),
    ] {
        response = response.with_header(Header::from_bytes(name.as_bytes(), value.as_bytes()).unwrap());
    }
    response
}

fn read_json_body(request: &mut Request) -> Result<Value, (Value, u16)> {
    let mut text = String::new();
    let mut limited = request.as_reader().take(MAX_BODY_BYTES as u64 + 1);
    limited
        .read_to_string(&mut text)
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 400))?;
    if text.len() > MAX_BODY_BYTES {
        return Err((json!({ "ok": false, "error": "request body too large" }), 413));
    }
    if text.trim().is_empty() {
        return Ok(json!({}));
    }
    serde_json::from_str(&text).map_err(|error| (json!({ "ok": false, "error": "invalid JSON request body", "detail": error.to_string() }), 400))
}

fn parse_url(request_url: &str) -> RequestUrl {
    let (path_raw, query_raw) = request_url.split_once('?').unwrap_or((request_url, ""));
    let path = if path_raw.is_empty() { "/" } else { path_raw }.to_string();
    let query = query_raw
        .split('&')
        .filter(|item| !item.is_empty())
        .map(|item| {
            let (key, value) = item.split_once('=').unwrap_or((item, ""));
            (percent_decode(key), percent_decode(value))
        })
        .collect();
    RequestUrl { path, query }
}

fn query_param(url: &RequestUrl, name: &str) -> Option<String> {
    url.query.iter().find(|(key, _)| key == name).map(|(_, value)| value.clone())
}

fn parse_i64(value: Option<String>, fallback: i64) -> i64 {
    value.and_then(|item| item.parse::<i64>().ok()).unwrap_or(fallback)
}

fn parse_usize(value: Option<String>, fallback: usize) -> usize {
    value.and_then(|item| item.parse::<usize>().ok()).unwrap_or(fallback)
}

fn validate_queue_id(value: &str) -> Result<String, String> {
    let text = value.trim();
    if text.is_empty() {
        return Ok(DEFAULT_QUEUE_ID.to_string());
    }
    if text.len() > 64 {
        return Err("queueId must be 64 characters or fewer".to_string());
    }
    let mut chars = text.chars();
    let Some(first) = chars.next() else {
        return Ok(DEFAULT_QUEUE_ID.to_string());
    };
    if !first.is_ascii_alphanumeric() {
        return Err("queueId must start with an ASCII letter or digit".to_string());
    }
    if !chars.all(|ch| ch.is_ascii_alphanumeric() || ch == '_' || ch == '.' || ch == '-') {
        return Err("queueId must match /^[A-Za-z0-9][A-Za-z0-9_.-]{0,63}$/".to_string());
    }
    Ok(text.to_string())
}

fn safe_queue_id(value: &str) -> String {
    validate_queue_id(value).unwrap_or_else(|_| DEFAULT_QUEUE_ID.to_string())
}

fn queue_name_from_value(value: Option<&Value>, queue_id: &str) -> Result<String, String> {
    let name = value.and_then(Value::as_str).unwrap_or(queue_id).trim();
    let normalized = name
        .chars()
        .map(|ch| if ch.is_control() { ' ' } else { ch })
        .collect::<String>()
        .split_whitespace()
        .collect::<Vec<_>>()
        .join(" ");
    let result = if normalized.is_empty() { queue_id.to_string() } else { normalized };
    if result.chars().count() > 80 {
        return Err("queue name must be 80 characters or fewer".to_string());
    }
    Ok(result)
}

fn preview(text: &str, max_chars: usize) -> String {
    if text.chars().count() <= max_chars {
        return text.to_string();
    }
    let take = max_chars.saturating_sub(20);
    let mut result = text.chars().take(take).collect::<String>();
    result.push_str("\n...<truncated>");
    result
}

fn text_preview(value: &str, max_chars: usize) -> Value {
    let chars = value.chars().count();
    let truncated = chars > max_chars;
    json!({
        "text": if truncated { preview(value, max_chars) } else { value.to_string() },
        "chars": chars,
        "truncated": truncated,
        "omittedChars": if truncated { chars.saturating_sub(max_chars.saturating_sub(20)) } else { 0 }
    })
}

fn strip_after_marker(text: &str, marker: &str) -> Option<String> {
    text.find(marker).map(|index| text[index + marker.len()..].trim_start().to_string())
}

fn user_prompt_for_display(prompt: &str) -> String {
    let trimmed = prompt.trim_start();
    if trimmed.starts_with("# Code Queue 运行环境提示") {
        if let Some(value) = strip_after_marker(prompt, "\n# 本次任务\n") {
            return value;
        }
    }
    if trimmed.starts_with("# Code Queue 已解析引用上下文") {
        if let Some(value) = strip_after_marker(prompt, "\n# 本次任务\n") {
            return value;
        }
    }
    prompt.to_string()
}

fn prompt_with_environment_hint(prompt: &str) -> String {
    if prompt.trim_start().starts_with("# Code Queue 运行环境提示") {
        return prompt.to_string();
    }
    [
        "# Code Queue 运行环境提示",
        "如果当前 Code Queue Docker 容器缺少完成任务所需的环境、系统包或语言依赖，可以先在容器内临时安装以推进当前任务；同时必须把该依赖补到 `src/components/microservices/code-queue/Dockerfile`，让后续任务重建镜像后可直接使用。",
        "",
        "# 本次任务",
        prompt.trim(),
    ]
    .join("\n")
}

fn terminal_status(status: &str) -> bool {
    matches!(status, "succeeded" | "failed" | "canceled")
}

fn active_status(status: &str) -> bool {
    matches!(status, "running" | "judging")
}

fn queued_prompt_editable(task: &TaskMeta) -> bool {
    task.status == "queued"
        && task.started_at.is_none()
        && task.current_attempt == 0
        && task.codex_thread_id.is_none()
        && task.active_turn_id.is_none()
        && task.task_json.as_ref().and_then(|value| value.get("nextMode")).map_or(true, Value::is_null)
        && task.task_json.as_ref().and_then(|value| value.get("nextPrompt")).map_or(true, Value::is_null)
        && task.attempt_count == 0
}

fn timing_json(task: &TaskMeta) -> Value {
    fn parse_ms(value: &Option<String>) -> Option<i64> {
        value
            .as_ref()
            .and_then(|text| chrono::DateTime::parse_from_rfc3339(text).ok())
            .map(|date| date.timestamp_millis())
    }
    let created = parse_ms(&Some(task.created_at.clone()));
    let started = parse_ms(&task.started_at);
    let finished = parse_ms(&task.finished_at);
    let updated = parse_ms(&Some(task.updated_at.clone()));
    let now = Utc::now().timestamp_millis();
    let queued_end = started.or(finished).or(updated).unwrap_or(now);
    json!({
        "queuedMs": created.map(|value| queued_end - value),
        "runMs": started.map(|value| finished.unwrap_or(now) - value),
        "totalElapsedMs": created.map(|value| finished.unwrap_or(now) - value),
        "durationMs": started.map(|value| finished.unwrap_or(now) - value)
    })
}

fn codex_stats_days_from_url(url: &RequestUrl) -> i64 {
    parse_i64(query_param(url, "days"), 14).clamp(1, 90)
}

fn codex_stats_queue_id_from_url(url: &RequestUrl) -> Option<String> {
    query_param(url, "queueId")
        .map(|value| value.trim().to_string())
        .filter(|value| !value.is_empty())
        .map(|value| safe_queue_id(&value))
}

fn codex_stats_range_sql() -> &'static str {
    "
    WITH stats_range AS (
      SELECT
        $2::int AS days,
        to_char(now() AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS end_date,
        (date_trunc('day', now() AT TIME ZONE 'Asia/Shanghai') - (($2::int - 1) * INTERVAL '1 day')) AT TIME ZONE 'Asia/Shanghai' AS start_at,
        (date_trunc('day', now() AT TIME ZONE 'Asia/Shanghai') + INTERVAL '1 day') AT TIME ZONE 'Asia/Shanghai' AS end_at
    ),
    day_series AS (
      SELECT to_char(day::date, 'YYYY-MM-DD') AS date
      FROM stats_range stats,
        generate_series(
          (stats.start_at AT TIME ZONE 'Asia/Shanghai')::date,
          (stats.end_at AT TIME ZONE 'Asia/Shanghai')::date - 1,
          INTERVAL '1 day'
        ) AS day
    ),
    executed AS (
      SELECT to_char(started_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date, COUNT(*)::bigint AS count
      FROM unidesk_code_queue_tasks, stats_range
      WHERE ($1::text IS NULL OR queue_id = $1)
        AND started_at >= stats_range.start_at
        AND started_at < stats_range.end_at
      GROUP BY date
    ),
    completed AS (
      SELECT
        to_char(COALESCE(finished_at, updated_at) AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date,
        COUNT(*)::bigint AS completed_tasks,
        COUNT(*) FILTER (WHERE status = 'succeeded')::bigint AS succeeded_tasks,
        COUNT(*) FILTER (WHERE status = 'failed')::bigint AS failed_tasks,
        COUNT(*) FILTER (WHERE status = 'canceled')::bigint AS canceled_tasks,
        COALESCE(SUM(GREATEST(EXTRACT(EPOCH FROM (COALESCE(finished_at, updated_at) - COALESCE(started_at, created_at))) * 1000, 0)), 0)::bigint AS total_duration_ms,
        COUNT(CASE WHEN COALESCE(started_at, created_at) IS NOT NULL THEN 1 END)::bigint AS duration_samples
      FROM unidesk_code_queue_tasks, stats_range
      WHERE ($1::text IS NULL OR queue_id = $1)
        AND status IN ('succeeded', 'failed', 'canceled')
        AND COALESCE(finished_at, updated_at) >= stats_range.start_at
        AND COALESCE(finished_at, updated_at) < stats_range.end_at
      GROUP BY date
    ),
    retries AS (
      SELECT
        to_char(updated_at AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD') AS date,
        SUM(GREATEST(current_attempt - 1, attempt_count - 1, 0))::bigint AS count
      FROM unidesk_code_queue_tasks, stats_range
      WHERE ($1::text IS NULL OR queue_id = $1)
        AND updated_at >= stats_range.start_at
        AND updated_at < stats_range.end_at
        AND GREATEST(current_attempt - 1, attempt_count - 1, 0) > 0
      GROUP BY date
    )
    SELECT
      day_series.date,
      COALESCE(executed.count, 0)::bigint AS executed_tasks,
      COALESCE(completed.completed_tasks, 0)::bigint AS completed_tasks,
      COALESCE(retries.count, 0)::bigint AS retry_attempts,
      COALESCE(completed.succeeded_tasks, 0)::bigint AS succeeded_tasks,
      COALESCE(completed.failed_tasks, 0)::bigint AS failed_tasks,
      COALESCE(completed.canceled_tasks, 0)::bigint AS canceled_tasks,
      COALESCE(completed.total_duration_ms, 0)::bigint AS total_duration_ms,
      COALESCE(completed.duration_samples, 0)::bigint AS duration_samples,
      (SELECT end_date FROM stats_range) AS end_date
    FROM day_series
    LEFT JOIN executed ON executed.date = day_series.date
    LEFT JOIN completed ON completed.date = day_series.date
    LEFT JOIN retries ON retries.date = day_series.date
    ORDER BY day_series.date ASC
    "
}

fn rounded_average_ms(total_duration_ms: i64, duration_samples: i64) -> Value {
    if duration_samples <= 0 {
        return Value::Null;
    }
    json!((total_duration_ms as f64 / duration_samples as f64).round() as i64)
}

fn codex_stats_summary_from_rows(days: i64, generated_at: &str, rows: &[DailyTaskStatsRow]) -> Value {
    let mut total_executed = 0_i64;
    let mut total_completed = 0_i64;
    let mut total_retries = 0_i64;
    let mut total_succeeded = 0_i64;
    let mut total_failed = 0_i64;
    let mut total_canceled = 0_i64;
    let mut total_duration_ms = 0_i64;
    let mut duration_samples = 0_i64;
    let daily = rows
        .iter()
        .map(|row| {
            total_executed += row.executed_tasks;
            total_completed += row.completed_tasks;
            total_retries += row.retry_attempts;
            total_succeeded += row.succeeded_tasks;
            total_failed += row.failed_tasks;
            total_canceled += row.canceled_tasks;
            total_duration_ms += row.total_duration_ms;
            duration_samples += row.duration_samples;
            json!({
                "date": row.date,
                "executedTasks": row.executed_tasks,
                "completedTasks": row.completed_tasks,
                "retryAttempts": row.retry_attempts,
                "succeededTasks": row.succeeded_tasks,
                "failedTasks": row.failed_tasks,
                "canceledTasks": row.canceled_tasks,
                "totalDurationMs": row.total_duration_ms,
                "durationSamples": row.duration_samples,
                "avgDurationMs": rounded_average_ms(row.total_duration_ms, row.duration_samples)
            })
        })
        .collect::<Vec<_>>();
    let start_date = rows.first().map(|row| row.date.clone()).unwrap_or_default();
    let end_date = rows.last().map(|row| row.date.clone()).unwrap_or_default();
    json!({
        "generatedAt": generated_at,
        "timezone": CODEX_STATS_TIME_ZONE,
        "days": days,
        "range": { "startDate": start_date, "endDate": end_date },
        "totals": {
            "executedTasks": total_executed,
            "completedTasks": total_completed,
            "retryAttempts": total_retries,
            "succeededTasks": total_succeeded,
            "failedTasks": total_failed,
            "canceledTasks": total_canceled,
            "totalDurationMs": total_duration_ms,
            "durationSamples": duration_samples,
            "avgDurationMs": rounded_average_ms(total_duration_ms, duration_samples)
        },
        "daily": daily
    })
}

fn task_statistics_summary(state: &AppState, queue_id: Option<String>, days: i64) -> Result<Value, String> {
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-stats")?;
    let rows = client
        .query(codex_stats_range_sql(), &[&queue_id, &days])
        .map_err(|error| error.to_string())?;
    let stats_rows = rows
        .iter()
        .map(|row| DailyTaskStatsRow {
            date: row.get("date"),
            executed_tasks: row.get("executed_tasks"),
            completed_tasks: row.get("completed_tasks"),
            retry_attempts: row.get("retry_attempts"),
            succeeded_tasks: row.get("succeeded_tasks"),
            failed_tasks: row.get("failed_tasks"),
            canceled_tasks: row.get("canceled_tasks"),
            total_duration_ms: row.get("total_duration_ms"),
            duration_samples: row.get("duration_samples"),
        })
        .collect::<Vec<_>>();
    Ok(codex_stats_summary_from_rows(days, &now_iso(), &stats_rows))
}

fn json_array_len(value: Option<&Value>, key: &str, fallback: i64) -> i64 {
    value
        .and_then(|json| json.get(key))
        .and_then(Value::as_array)
        .map(|items| items.len() as i64)
        .unwrap_or(fallback)
}

fn output_array(task: &TaskMeta) -> Vec<Value> {
    task.task_json
        .as_ref()
        .and_then(|value| value.get("output"))
        .and_then(Value::as_array)
        .cloned()
        .unwrap_or_default()
}

fn attempts_array(task: &TaskMeta) -> Vec<Value> {
    task.task_json
        .as_ref()
        .and_then(|value| value.get("attempts"))
        .and_then(Value::as_array)
        .cloned()
        .unwrap_or_default()
}

fn final_response(task: &TaskMeta) -> String {
    task.task_json
        .as_ref()
        .and_then(|value| value.get("finalResponse"))
        .and_then(Value::as_str)
        .unwrap_or("")
        .to_string()
}

fn text_from_output(item: &Value) -> String {
    item.get("text").and_then(Value::as_str).unwrap_or("").to_string()
}

fn seq_from_output(item: &Value) -> i64 {
    item.get("seq").and_then(Value::as_i64).unwrap_or(0)
}

fn output_max_seq(task: &TaskMeta) -> i64 {
    let from_output = output_array(task).iter().map(seq_from_output).max().unwrap_or(0);
    task.last_output_seq.max(from_output)
}

fn trace_countable_outputs(task: &TaskMeta) -> Vec<Value> {
    output_array(task)
        .into_iter()
        .filter(|item| !(item.get("channel").and_then(Value::as_str) == Some("system") && item.get("method").and_then(Value::as_str) == Some("enqueue")))
        .collect()
}

fn configured_step_count(task: &TaskMeta) -> Option<i64> {
    task.task_json.as_ref().and_then(|value| value.get("stepCount")).and_then(Value::as_i64)
}

fn raw_trace_step_count(task: &TaskMeta) -> i64 {
    let output_count = trace_countable_outputs(task).len() as i64;
    let output_count = if output_count > 0 { output_count } else { task.output_count };
    configured_step_count(task).unwrap_or(output_count).max(output_count)
}

fn trace_stats_contract(scope_id: &str, step_count: i64, output_max_seq: i64) -> Value {
    json!({
        "scopeId": scope_id,
        "source": "oa-event-flow",
        "sourceHint": "raw-trace-fallback",
        "stepCount": step_count,
        "llmStepCount": 0,
        "toolCallCount": step_count,
        "editedFileCount": 0,
        "commandCount": 0,
        "firstSeq": if step_count > 0 { json!(1) } else { Value::Null },
        "lastSeq": if output_max_seq > 0 { json!(output_max_seq) } else { Value::Null },
        "computedAt": now_iso(),
        "incomplete": true
    })
}

fn trace_execution_contract(scope_id: &str, step_count: i64, output_max_seq: i64) -> Value {
    let trace_stats = if step_count > 0 || output_max_seq > 0 {
        trace_stats_contract(scope_id, step_count, output_max_seq)
    } else {
        Value::Null
    };
    json!({
        "stepCount": step_count,
        "llmStepCount": 0,
        "toolCallCount": step_count,
        "editedFileCount": 0,
        "commandCount": 0,
        "traceStats": trace_stats,
        "statsSource": if step_count > 0 || output_max_seq > 0 { "raw-trace-fallback" } else { "raw-trace-empty" },
        "traceStatsState": if step_count > 0 || output_max_seq > 0 { "degraded" } else { "empty" },
        "traceStatsReason": if step_count > 0 || output_max_seq > 0 { "oa-event-flow-stats-unavailable-raw-trace-present" } else { "no-trace-steps-yet" },
        "statsUnavailable": true,
        "statsSyncing": step_count > 0 || output_max_seq > 0,
        "rawTraceStepCount": step_count
    })
}

fn attempt_index_from_value(value: &Value) -> Option<i64> {
    value
        .get("index")
        .or_else(|| value.get("attempt"))
        .or_else(|| value.get("attemptIndex"))
        .and_then(Value::as_i64)
        .filter(|index| *index > 0)
}

fn output_attempt_index(task: &TaskMeta, item: &Value) -> i64 {
    if let Some(index) = item
        .get("attempt")
        .or_else(|| item.get("attemptIndex"))
        .and_then(Value::as_i64)
        .filter(|index| *index > 0)
    {
        return index;
    }
    let seq = seq_from_output(item);
    for attempt in attempts_array(task) {
        let Some(index) = attempt_index_from_value(&attempt) else { continue };
        let start = attempt.get("outputStartSeq").and_then(Value::as_i64).unwrap_or(i64::MIN);
        let end = attempt.get("outputEndSeq").and_then(Value::as_i64).unwrap_or(i64::MAX);
        if seq >= start && seq <= end {
            return index;
        }
    }
    task.current_attempt.max(1)
}

fn attempt_indexes_for_trace(task: &TaskMeta, outputs: &[Value]) -> Vec<i64> {
    let mut indexes = BTreeSet::new();
    for attempt in attempts_array(task) {
        if let Some(index) = attempt_index_from_value(&attempt) {
            indexes.insert(index);
        }
    }
    if task.current_attempt > 0 {
        indexes.insert(task.current_attempt);
    }
    for item in outputs {
        indexes.insert(output_attempt_index(task, item));
    }
    indexes.into_iter().collect()
}

fn attempt_trace_window(task: &TaskMeta, outputs: &[Value], index: i64) -> Value {
    let existing = attempts_array(task)
        .into_iter()
        .find(|attempt| attempt_index_from_value(attempt) == Some(index));
    let attempt_outputs: Vec<&Value> = outputs.iter().filter(|item| output_attempt_index(task, item) == index).collect();
    let step_count = attempt_outputs.len() as i64;
    let output_max = attempt_outputs.iter().map(|item| seq_from_output(item)).max().unwrap_or(0);
    let scope_id = format!("task:{}:attempt:{}", task.id, index);
    let mut record = existing.and_then(|value| value.as_object().cloned()).unwrap_or_else(Map::new);
    record.insert("index".to_string(), json!(index));
    record.entry("mode".to_string()).or_insert_with(|| {
        if index == task.current_attempt {
            task.current_mode.as_ref().map(|value| json!(value)).unwrap_or(Value::Null)
        } else {
            Value::Null
        }
    });
    record.insert("stepCount".to_string(), json!(step_count));
    record.insert("retainedStepCount".to_string(), json!(step_count));
    record.insert("outputMaxSeq".to_string(), json!(output_max));
    record.insert("traceStats".to_string(), if step_count > 0 { trace_stats_contract(&scope_id, step_count, output_max) } else { Value::Null });
    record.insert("statsSource".to_string(), json!(if step_count > 0 { "raw-trace-fallback" } else { "raw-trace-empty" }));
    record.insert("traceStatsState".to_string(), json!(if step_count > 0 { "degraded" } else { "empty" }));
    record.insert("traceStatsReason".to_string(), json!(if step_count > 0 { "oa-event-flow-stats-unavailable-raw-trace-present" } else { "no-trace-steps-yet" }));
    record.insert("statsUnavailable".to_string(), json!(true));
    record.insert("statsSyncing".to_string(), json!(step_count > 0));
    record.insert("rawTraceStepCount".to_string(), json!(step_count));
    record.insert("execution".to_string(), trace_execution_contract(&scope_id, step_count, output_max));
    Value::Object(record)
}

fn task_scheduler_heartbeat(task: &TaskMeta) -> Option<Value> {
    task.task_json
        .as_ref()
        .and_then(|value| value.get("schedulerHeartbeat"))
        .filter(|value| value.is_object())
        .cloned()
}

fn parse_iso_ms(value: Option<&str>) -> Option<i64> {
    value
        .and_then(|text| DateTime::parse_from_rfc3339(text).ok())
        .map(|date| date.timestamp_millis())
}

fn heartbeat_string_field(heartbeat: &Value, key: &str) -> Option<String> {
    heartbeat.get(key).and_then(Value::as_str).map(|value| value.to_string())
}

fn heartbeat_task_id(heartbeat: &Value) -> String {
    heartbeat_string_field(heartbeat, "taskId").unwrap_or_default()
}

fn heartbeat_fresh(heartbeat: &Value, now_ms: i64) -> bool {
    parse_iso_ms(heartbeat.get("lastLocalHeartbeatAt").and_then(Value::as_str))
        .map(|at| now_ms.saturating_sub(at) < SCHEDULER_HEARTBEAT_STALE_MS)
        .unwrap_or(false)
}

fn max_timestamp(values: Vec<Option<String>>) -> Value {
    let mut best: Option<(String, i64)> = None;
    for value in values.into_iter().flatten() {
        let Some(ms) = parse_iso_ms(Some(&value)) else { continue };
        if best.as_ref().map(|(_, best_ms)| ms >= *best_ms).unwrap_or(true) {
            best = Some((value, ms));
        }
    }
    best.map(|(value, _)| json!(value)).unwrap_or(Value::Null)
}

fn task_has_trace_gap(task: &TaskMeta, heartbeat: &Value, now_ms: i64) -> bool {
    let trace_ms = parse_iso_ms(heartbeat.get("lastPersistedTraceAt").and_then(Value::as_str));
    let output_seq = heartbeat.get("outputMaxSeq").and_then(Value::as_i64).unwrap_or_else(|| output_max_seq(task));
    trace_ms
        .map(|at| now_ms.saturating_sub(at) >= SCHEDULER_HEARTBEAT_STALE_MS && output_seq > 0)
        .unwrap_or(false)
}

fn execution_diagnostics_from_tasks(tasks: &[TaskMeta], now: &str) -> Value {
    let now_ms = parse_iso_ms(Some(now)).unwrap_or_else(|| Utc::now().timestamp_millis());
    let mut database_active_task_ids: Vec<String> = tasks.iter().filter(|task| active_status(&task.status)).map(|task| task.id.clone()).collect();
    database_active_task_ids.sort();

    let mut active_heartbeats: Vec<(String, Value)> = tasks
        .iter()
        .filter_map(|task| task_scheduler_heartbeat(task).map(|heartbeat| (task.id.clone(), heartbeat)))
        .collect();
    active_heartbeats.sort_by(|left, right| left.0.cmp(&right.0));

    let mut active_heartbeat_task_ids: Vec<String> = active_heartbeats.iter().map(|(_, heartbeat)| heartbeat_task_id(heartbeat)).filter(|id| !id.is_empty()).collect();
    active_heartbeat_task_ids.sort();
    active_heartbeat_task_ids.dedup();

    let mut heartbeat_fresh_task_ids: Vec<String> = active_heartbeats
        .iter()
        .filter(|(_, heartbeat)| heartbeat_fresh(heartbeat, now_ms))
        .map(|(_, heartbeat)| heartbeat_task_id(heartbeat))
        .filter(|id| !id.is_empty())
        .collect();
    heartbeat_fresh_task_ids.sort();
    heartbeat_fresh_task_ids.dedup();

    let mut heartbeat_expired_task_ids: Vec<String> = active_heartbeats
        .iter()
        .filter(|(task_id, heartbeat)| {
            tasks.iter().any(|task| &task.id == task_id && active_status(&task.status))
                && !heartbeat_fresh(heartbeat, now_ms)
        })
        .map(|(_, heartbeat)| heartbeat_task_id(heartbeat))
        .filter(|id| !id.is_empty())
        .collect();
    heartbeat_expired_task_ids.sort();
    heartbeat_expired_task_ids.dedup();

    let heartbeat_task_set: HashSet<String> = active_heartbeat_task_ids.iter().cloned().collect();
    let heartbeat_fresh_set: HashSet<String> = heartbeat_fresh_task_ids.iter().cloned().collect();
    let heartbeat_expired_set: HashSet<String> = heartbeat_expired_task_ids.iter().cloned().collect();
    let heartbeat_missing_task_ids: Vec<String> = database_active_task_ids
        .iter()
        .filter(|task_id| !heartbeat_task_set.contains(*task_id))
        .cloned()
        .collect();
    let stale_recovery_candidate_task_ids: Vec<String> = database_active_task_ids
        .iter()
        .filter(|task_id| heartbeat_expired_set.contains(*task_id))
        .cloned()
        .collect();
    let mut heartbeat_risk_task_ids: Vec<String> = heartbeat_expired_task_ids
        .iter()
        .chain(heartbeat_missing_task_ids.iter())
        .chain(stale_recovery_candidate_task_ids.iter())
        .cloned()
        .collect();
    heartbeat_risk_task_ids.sort();
    heartbeat_risk_task_ids.dedup();
    let mut trace_gap_task_ids: Vec<String> = active_heartbeats
        .iter()
        .filter(|(task_id, heartbeat)| {
            tasks.iter().find(|task| &task.id == task_id).map(|task| task_has_trace_gap(task, heartbeat, now_ms)).unwrap_or(false)
        })
        .map(|(_, heartbeat)| heartbeat_task_id(heartbeat))
        .filter(|id| !id.is_empty())
        .collect();
    trace_gap_task_ids.sort();
    trace_gap_task_ids.dedup();
    let trace_gap_not_stale_task_ids: Vec<String> = trace_gap_task_ids
        .iter()
        .filter(|task_id| heartbeat_fresh_set.contains(*task_id))
        .cloned()
        .collect();

    let split_brain = !database_active_task_ids.is_empty() && !heartbeat_fresh_task_ids.is_empty();
    let split_brain_live = split_brain && heartbeat_risk_task_ids.is_empty();
    let stale_active = !stale_recovery_candidate_task_ids.is_empty();
    let degraded = split_brain
        || stale_active
        || !heartbeat_missing_task_ids.is_empty()
        || !heartbeat_expired_task_ids.is_empty()
        || !trace_gap_task_ids.is_empty();
    let state = if split_brain {
        "split-brain"
    } else if stale_active {
        "stale-active"
    } else if degraded {
        "degraded"
    } else {
        "healthy"
    };
    let effective_liveness = if !heartbeat_risk_task_ids.is_empty() {
        "at-risk"
    } else if split_brain_live {
        "live"
    } else if degraded {
        "degraded"
    } else {
        "healthy"
    };
    let recommended_action = if !heartbeat_risk_task_ids.is_empty() {
        "investigate-heartbeat-risk"
    } else if split_brain_live {
        "continue-supervision"
    } else if degraded {
        "observe-degraded"
    } else {
        "none"
    };
    let liveness_summary = if !heartbeat_risk_task_ids.is_empty() {
        "Heartbeat is expired, missing, or stale-recovery eligible for at least one database-active task; investigate before assuming the task is still live."
    } else if split_brain_live {
        "PostgreSQL and the local control-plane view are split, but scheduler-owned heartbeat is fresh; treat the task as live and continue supervision."
    } else if degraded {
        "Execution diagnostics are degraded; inspect the listed reasons together with heartbeat and trace progress."
    } else {
        "Execution diagnostics are healthy."
    };
    let mut reasons = Vec::new();
    if split_brain {
        reasons.push("postgres control-plane has database-active tasks while its local active slots are empty, but scheduler heartbeat is fresh");
    }
    if stale_active {
        reasons.push("owner heartbeat is expired and scheduler has no local active run for at least one database-active task");
    }
    if !heartbeat_missing_task_ids.is_empty() {
        reasons.push("database-active tasks are missing scheduler-owned heartbeat");
    }
    if !trace_gap_not_stale_task_ids.is_empty() {
        reasons.push("trace progress is stale while scheduler heartbeat is fresh; this is a trace gap, not stale active");
    }
    let database_active_task_count = database_active_task_ids.len();
    let scheduler_orphaned_active_task_ids = database_active_task_ids.clone();
    let scheduler_orphaned_active_task_count = scheduler_orphaned_active_task_ids.len();
    let active_heartbeat_count = active_heartbeat_task_ids.len();
    let last_scheduler_heartbeat_at = max_timestamp(active_heartbeats.iter().map(|(_, heartbeat)| heartbeat_string_field(heartbeat, "lastLocalHeartbeatAt")).collect());
    let last_observed_agent_event_at = max_timestamp(active_heartbeats.iter().map(|(_, heartbeat)| heartbeat_string_field(heartbeat, "lastObservedAgentEventAt")).collect());
    let last_persisted_trace_at = max_timestamp(active_heartbeats.iter().map(|(_, heartbeat)| heartbeat_string_field(heartbeat, "lastPersistedTraceAt")).collect());

    json!({
        "state": state,
        "health": state,
        "degraded": degraded,
        "splitBrain": split_brain,
        "splitBrainLive": split_brain_live,
        "effectiveLiveness": effective_liveness,
        "recommendedAction": recommended_action,
        "livenessSummary": liveness_summary,
        "executionStateSource": "postgres-control-plane",
        "controlPlane": "master-code-queue-mgr",
        "databaseActiveTaskIds": database_active_task_ids,
        "databaseActiveTaskCount": database_active_task_count,
        "schedulerActiveTaskIds": [],
        "schedulerActiveTaskCount": 0,
        "schedulerActiveRunSlotCount": 0,
        "schedulerActiveQueueIds": [],
        "schedulerProcessingQueueIds": [],
        "schedulerOrphanedActiveTaskIds": scheduler_orphaned_active_task_ids,
        "schedulerOrphanedActiveTaskCount": scheduler_orphaned_active_task_count,
        "activeHeartbeatTaskIds": active_heartbeat_task_ids,
        "activeHeartbeatCount": active_heartbeat_count,
        "heartbeatFreshTaskIds": heartbeat_fresh_task_ids,
        "heartbeatExpiredTaskIds": heartbeat_expired_task_ids,
        "heartbeatMissingTaskIds": heartbeat_missing_task_ids,
        "staleRecoveryCandidateTaskIds": stale_recovery_candidate_task_ids,
        "heartbeatRiskTaskIds": heartbeat_risk_task_ids,
        "traceGapTaskIds": trace_gap_task_ids,
        "traceGapNotStaleTaskIds": trace_gap_not_stale_task_ids,
        "schedulerHeartbeatStaleMs": SCHEDULER_HEARTBEAT_STALE_MS,
        "now": now,
        "lastSchedulerHeartbeatAt": last_scheduler_heartbeat_at,
        "lastObservedAgentEventAt": last_observed_agent_event_at,
        "lastPersistedTraceAt": last_persisted_trace_at,
        "oaPublisher": Value::Null,
        "reasons": reasons,
        "guidance": [
            "Do not use master activeRunSlotCount=0 alone to declare a task stuck.",
            "Check PostgreSQL task status, scheduler active runs/slots, scheduler heartbeat, and trace/OA publisher progress together.",
            "Trace gap with a fresh scheduler heartbeat must not trigger stale retry.",
            "Stale recovery is allowed only when the scheduler has no local active run and the owner heartbeat is expired."
        ]
    })
}

fn last_assistant_message(task: &TaskMeta) -> Value {
    let final_text = final_response(task);
    if !final_text.trim().is_empty() {
        return json!({
            "text": final_text,
            "at": task.finished_at.clone().unwrap_or_else(|| task.updated_at.clone()),
            "seq": Value::Null,
            "source": "finalResponse"
        });
    }
    for item in output_array(task).iter().rev() {
        if item.get("channel").and_then(Value::as_str) == Some("assistant") {
            return json!({
                "text": text_from_output(item),
                "at": item.get("at").cloned().unwrap_or_else(|| json!(task.updated_at)),
                "seq": item.get("seq").cloned().unwrap_or(Value::Null),
                "source": "output"
            });
        }
    }
    json!({ "text": "", "at": task.updated_at, "seq": Value::Null, "source": "none" })
}

fn task_list_response(_state: &AppState, task: &TaskMeta, lite: bool) -> Value {
    let display_prompt = if task.base_prompt.is_empty() {
        user_prompt_for_display(&task.prompt)
    } else {
        task.base_prompt.clone()
    };
    let output_count = json_array_len(task.task_json.as_ref(), "output", task.output_count);
    let event_count = json_array_len(task.task_json.as_ref(), "events", task.event_count);
    let attempt_count = json_array_len(task.task_json.as_ref(), "attempts", task.attempt_count);
    let attempts = attempts_array(task);
    let attempt_preview = if lite && attempts.len() > 3 {
        attempts[attempts.len() - 3..].to_vec()
    } else {
        attempts
    };
    let final_text = final_response(task);
    let agent_port = code_agent_port(&task.model);
    let preview_limit = if lite { 360 } else { 2000 };
    let raw_step_count = raw_trace_step_count(task);
    let execution = trace_execution_contract(&format!("task:{}", task.id), raw_step_count, output_max_seq(task));
    let trace_stats = execution.get("traceStats").cloned().unwrap_or(Value::Null);
    json!({
        "id": task.id,
        "queueId": task.queue_id,
        "queueEnteredAt": task.task_json.as_ref().and_then(|value| value.get("queueEnteredAt")).and_then(Value::as_str).unwrap_or(&task.created_at),
        "prompt": task.prompt,
        "basePrompt": task.base_prompt,
        "displayPrompt": display_prompt,
        "promptPreview": text_preview(&task.prompt, preview_limit),
        "basePromptPreview": text_preview(&task.base_prompt, preview_limit),
        "displayPromptPreview": text_preview(&display_prompt, preview_limit),
        "promptChars": task.prompt.chars().count(),
        "basePromptChars": task.base_prompt.chars().count(),
        "displayPromptChars": display_prompt.chars().count(),
        "promptEditable": queued_prompt_editable(task),
        "finalResponseChars": final_text.chars().count(),
        "stepCount": raw_step_count,
        "llmStepCount": task.task_json.as_ref().and_then(|value| value.get("llmStepCount")).and_then(Value::as_i64).unwrap_or(task.last_output_seq),
        "traceStats": trace_stats,
        "statsSource": execution.get("statsSource").cloned().unwrap_or_else(|| json!("raw-trace-empty")),
        "traceStatsState": execution.get("traceStatsState").cloned().unwrap_or_else(|| json!("empty")),
        "traceStatsReason": execution.get("traceStatsReason").cloned().unwrap_or_else(|| json!("no-trace-steps-yet")),
        "statsUnavailable": true,
        "statsSyncing": raw_step_count > 0,
        "rawTraceStepCount": raw_step_count,
        "execution": execution,
        "summaryOnly": true,
        "referenceTaskIds": task.reference_task_ids,
        "referenceInjection": task.reference_injection,
        "providerId": task.provider_id,
        "executionMode": task.execution_mode,
        "executionModeInfo": execution_mode_info(&task.execution_mode),
        "cwd": task.cwd,
        "model": task.model,
        "agentPort": agent_port,
        "agentPortInfo": code_agent_port_info(agent_port),
        "reasoningEffort": task.reasoning_effort,
        "maxAttempts": task.max_attempts,
        "status": task.status,
        "queuedReason": if task.status == "queued" || task.status == "retry_wait" {
            json!({ "code": "mgr-visible", "label": if task.status == "retry_wait" { "RETRY" } else { "QUEUED" }, "message": "Task is visible from master code-queue-mgr; D601 scheduler will pick it up from PostgreSQL." })
        } else {
            Value::Null
        },
        "queuedReasonLabel": if task.status == "retry_wait" { json!("RETRY") } else if task.status == "queued" { json!("QUEUED") } else { Value::Null },
        "createdAt": task.created_at,
        "updatedAt": task.updated_at,
        "startedAt": task.started_at,
        "finishedAt": task.finished_at,
        "readAt": task.read_at,
        "currentAttempt": task.current_attempt,
        "currentMode": task.current_mode,
        "judgeFailCount": task.task_json.as_ref().and_then(|value| value.get("judgeFailCount")).and_then(Value::as_i64).unwrap_or(0),
        "judgeFailRetryLimit": 3,
        "schedulerHeartbeat": task_scheduler_heartbeat(task).unwrap_or(Value::Null),
        "codexThreadId": task.codex_thread_id,
        "activeTurnId": task.active_turn_id,
        "lastError": task.last_error,
        "lastJudge": task.last_judge,
        "cancelRequested": task.task_json.as_ref().and_then(|value| value.get("cancelRequested")).and_then(Value::as_bool).unwrap_or(false),
        "terminalUnread": terminal_status(&task.status) && task.read_at.is_none(),
        "outputCount": output_count,
        "eventCount": event_count,
        "attemptCount": attempt_count,
        "attempts": attempt_preview,
        "timing": timing_json(task),
        "_runtime": "rust",
        "_readPath": "column-first"
    })
}

fn task_meta_response(state: &AppState, task: &TaskMeta) -> Value {
    let mut base = task_list_response(state, task, false);
    let map = base.as_object_mut().expect("task response object");
    let output_count = json_array_len(task.task_json.as_ref(), "output", task.output_count);
    let prompt_history_count = json_array_len(task.task_json.as_ref(), "promptHistory", 0);
    let display_prompt = if task.base_prompt.is_empty() {
        user_prompt_for_display(&task.prompt)
    } else {
        task.base_prompt.clone()
    };
    let trace_outputs = trace_countable_outputs(task);
    let raw_step_count = raw_trace_step_count(task);
    let execution = trace_execution_contract(&format!("task:{}", task.id), raw_step_count, output_max_seq(task));
    let trace_stats = execution.get("traceStats").cloned().unwrap_or(Value::Null);
    let attempts = attempt_indexes_for_trace(task, &trace_outputs)
        .into_iter()
        .map(|index| attempt_trace_window(task, &trace_outputs, index))
        .collect::<Vec<_>>();
    map.insert("prompt".to_string(), json!(task.prompt));
    map.insert("basePrompt".to_string(), json!(task.base_prompt));
    map.insert("displayPrompt".to_string(), json!(display_prompt));
    map.insert("initialPrompt".to_string(), json!(task.prompt));
    map.insert("finalResponse".to_string(), json!(final_response(task)));
    map.insert(
        "promptHistory".to_string(),
        task.task_json.as_ref().and_then(|value| value.get("promptHistory")).cloned().unwrap_or_else(|| json!([])),
    );
    map.insert("attempts".to_string(), json!(attempts));
    map.insert(
        "nextMode".to_string(),
        task.task_json.as_ref().and_then(|value| value.get("nextMode")).cloned().unwrap_or(Value::Null),
    );
    map.insert("outputCount".to_string(), json!(output_count));
    map.insert("retainedOutputCount".to_string(), json!(output_count));
    map.insert("eventCount".to_string(), json!(json_array_len(task.task_json.as_ref(), "events", task.event_count)));
    map.insert("transcriptCount".to_string(), json!(output_count + prompt_history_count));
    map.insert("transcriptMaxSeq".to_string(), json!(output_max_seq(task)));
    map.insert("transcript".to_string(), json!([]));
    map.insert("output".to_string(), json!([]));
    map.insert("events".to_string(), json!([]));
    map.insert("summaryOnly".to_string(), json!(false));
    map.insert("stepCount".to_string(), json!(raw_step_count));
    map.insert("llmStepCount".to_string(), json!(task.task_json.as_ref().and_then(|value| value.get("llmStepCount")).and_then(Value::as_i64).unwrap_or(task.last_output_seq)));
    map.insert("traceStats".to_string(), trace_stats);
    map.insert("statsSource".to_string(), execution.get("statsSource").cloned().unwrap_or_else(|| json!("raw-trace-empty")));
    map.insert("traceStatsState".to_string(), execution.get("traceStatsState").cloned().unwrap_or_else(|| json!("empty")));
    map.insert("traceStatsReason".to_string(), execution.get("traceStatsReason").cloned().unwrap_or_else(|| json!("no-trace-steps-yet")));
    map.insert("statsUnavailable".to_string(), json!(true));
    map.insert("statsSyncing".to_string(), json!(raw_step_count > 0));
    map.insert("rawTraceStepCount".to_string(), json!(raw_step_count));
    map.insert("execution".to_string(), execution);
    base
}

fn row_to_task(row: &postgres::Row, include_task_json: bool) -> TaskMeta {
    TaskMeta {
        id: row.get("id"),
        queue_id: safe_queue_id(row.get::<_, String>("queue_id").as_str()),
        status: row.get("status"),
        provider_id: row.get("provider_id"),
        execution_mode: row.get("execution_mode"),
        model: row.get("model"),
        cwd: row.get("cwd"),
        prompt: row.get("prompt"),
        base_prompt: row.get("base_prompt"),
        reference_task_ids: row.get("reference_task_ids"),
        reference_injection: row.get("reference_injection"),
        reasoning_effort: row.get("reasoning_effort"),
        max_attempts: row.get::<_, i32>("max_attempts") as i64,
        current_attempt: row.get::<_, i32>("current_attempt") as i64,
        current_mode: row.get("current_mode"),
        codex_thread_id: row.get("codex_thread_id"),
        active_turn_id: row.get("active_turn_id"),
        created_at: row.get("created_at"),
        updated_at: row.get("updated_at"),
        started_at: row.get("started_at"),
        finished_at: row.get("finished_at"),
        read_at: row.get("read_at"),
        last_error: row.get("last_error"),
        last_judge: row.get("last_judge"),
        output_count: row.get::<_, i32>("output_count") as i64,
        event_count: row.get::<_, i32>("event_count") as i64,
        attempt_count: row.get::<_, i32>("attempt_count") as i64,
        last_output_seq: row.get::<_, i64>("last_output_seq"),
        task_json: if include_task_json { row.get("task_json") } else { None },
    }
}

fn load_task(state: &AppState, task_id: &str, include_full_json: bool) -> Result<Option<TaskMeta>, String> {
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-task")?;
    let task_json_sql = if include_full_json { "task_json" } else { "task_json - 'output' - 'events' - 'promptHistory'" };
    let query = format!(
        "
        SELECT id, queue_id, status, provider_id, execution_mode, model, cwd, prompt, base_prompt,
          reference_task_ids, reference_injection, reasoning_effort, max_attempts, current_attempt,
          current_mode, codex_thread_id, active_turn_id,
          to_json(created_at)#>>'{{}}' AS created_at,
          to_json(updated_at)#>>'{{}}' AS updated_at,
          to_json(started_at)#>>'{{}}' AS started_at,
          to_json(finished_at)#>>'{{}}' AS finished_at,
          to_json(read_at)#>>'{{}}' AS read_at,
          last_error, last_judge, output_count, event_count, attempt_count, last_output_seq,
          {task_json_sql} AS task_json
        FROM unidesk_code_queue_tasks
        WHERE id = $1
        LIMIT 1
        "
    );
    let rows = client.query(&query, &[&task_id]).map_err(|error| error.to_string())?;
    Ok(rows.first().map(|row| row_to_task(row, true)))
}

fn load_tasks_for_list(state: &AppState, url: &RequestUrl, include_compact_json: bool) -> Result<(Vec<TaskMeta>, i64, i64, i64), String> {
    let limit = parse_i64(query_param(url, "limit"), 100).clamp(1, MAX_LIST_LIMIT);
    let offset = parse_i64(query_param(url, "offset"), 0).max(0);
    let status = query_param(url, "status").filter(|value| !value.is_empty());
    let queue_id = query_param(url, "queueId").filter(|value| !value.is_empty()).map(|value| safe_queue_id(&value));
    let search = query_param(url, "q")
        .or_else(|| query_param(url, "search"))
        .unwrap_or_default()
        .trim()
        .to_string();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-list")?;
    let task_json_sql = if include_compact_json { "task_json - 'output' - 'events' - 'promptHistory'" } else { "NULL::jsonb" };
    let query = format!(
        "
        SELECT id, queue_id, status, provider_id, execution_mode, model, cwd, prompt, base_prompt,
          reference_task_ids, reference_injection, reasoning_effort, max_attempts, current_attempt,
          current_mode, codex_thread_id, active_turn_id,
          to_json(created_at)#>>'{{}}' AS created_at,
          to_json(updated_at)#>>'{{}}' AS updated_at,
          to_json(started_at)#>>'{{}}' AS started_at,
          to_json(finished_at)#>>'{{}}' AS finished_at,
          to_json(read_at)#>>'{{}}' AS read_at,
          last_error, last_judge, output_count, event_count, attempt_count, last_output_seq,
          {task_json_sql} AS task_json,
          COUNT(*) OVER() AS total_count
        FROM unidesk_code_queue_tasks
        WHERE ($1::text IS NULL OR status = $1)
          AND ($2::text IS NULL OR queue_id = $2)
          AND ($3::text = '' OR id ILIKE ('%' || $3 || '%') OR prompt ILIKE ('%' || $3 || '%') OR base_prompt ILIKE ('%' || $3 || '%') OR COALESCE(last_error, '') ILIKE ('%' || $3 || '%'))
        ORDER BY
          CASE status WHEN 'running' THEN 0 WHEN 'judging' THEN 1 WHEN 'retry_wait' THEN 2 WHEN 'queued' THEN 3 ELSE 8 END ASC,
          updated_at DESC,
          id DESC
        LIMIT $4
        OFFSET $5
        "
    );
    let rows = client
        .query(&query, &[&status, &queue_id, &search, &limit, &offset])
        .map_err(|error| error.to_string())?;
    let total = rows.first().map(|row| row.get::<_, i64>("total_count")).unwrap_or(0);
    Ok((rows.iter().map(|row| row_to_task(row, include_compact_json)).collect(), total, limit, offset))
}

fn queue_summary(state: &AppState) -> Result<Value, String> {
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-queue-summary")?;
    let rows = client
        .query(
            "
            WITH queue_ids AS (
              SELECT id FROM unidesk_code_queue_queues
              UNION
              SELECT DISTINCT queue_id AS id FROM unidesk_code_queue_tasks
            ),
            queue_base AS (
              SELECT
                qi.id,
                COALESCE(q.name, qi.id) AS name,
                to_json(q.created_at)#>>'{}' AS created_at,
                to_json(q.updated_at)#>>'{}' AS updated_at
              FROM queue_ids qi
              LEFT JOIN unidesk_code_queue_queues q ON q.id = qi.id
            ),
            task_counts AS (
              SELECT queue_id,
                COUNT(*)::bigint AS total,
                COUNT(*) FILTER (WHERE status = 'queued')::bigint AS queued,
                COUNT(*) FILTER (WHERE status = 'running')::bigint AS running,
                COUNT(*) FILTER (WHERE status = 'judging')::bigint AS judging,
                COUNT(*) FILTER (WHERE status = 'retry_wait')::bigint AS retry_wait,
                COUNT(*) FILTER (WHERE status = 'succeeded')::bigint AS succeeded,
                COUNT(*) FILTER (WHERE status = 'failed')::bigint AS failed,
                COUNT(*) FILTER (WHERE status = 'canceled')::bigint AS canceled,
                COUNT(*) FILTER (WHERE status IN ('succeeded', 'failed', 'canceled') AND read_at IS NULL)::bigint AS unread_terminal,
                MIN(id) FILTER (WHERE status IN ('queued', 'retry_wait')) AS runnable_task_id,
                MIN(id) FILTER (WHERE status IN ('running', 'judging')) AS active_task_id
              FROM unidesk_code_queue_tasks
              GROUP BY queue_id
            )
            SELECT qb.id, qb.name, qb.created_at, qb.updated_at,
              COALESCE(tc.total, 0)::bigint AS total,
              COALESCE(tc.queued, 0)::bigint AS queued,
              COALESCE(tc.running, 0)::bigint AS running,
              COALESCE(tc.judging, 0)::bigint AS judging,
              COALESCE(tc.retry_wait, 0)::bigint AS retry_wait,
              COALESCE(tc.succeeded, 0)::bigint AS succeeded,
              COALESCE(tc.failed, 0)::bigint AS failed,
              COALESCE(tc.canceled, 0)::bigint AS canceled,
              COALESCE(tc.unread_terminal, 0)::bigint AS unread_terminal,
              tc.runnable_task_id,
              tc.active_task_id
            FROM queue_base qb
            LEFT JOIN task_counts tc ON tc.queue_id = qb.id
            ORDER BY qb.id ASC
            ",
            &[],
        )
        .map_err(|error| error.to_string())?;
    let mut queues = Vec::new();
    let mut counts = Map::new();
    let mut total = 0_i64;
    let mut unread_terminal_total = 0_i64;
    for row in rows {
        let id = safe_queue_id(row.get::<_, String>("id").as_str());
        let status_counts = json!({
            "queued": row.get::<_, i64>("queued"),
            "running": row.get::<_, i64>("running"),
            "judging": row.get::<_, i64>("judging"),
            "retry_wait": row.get::<_, i64>("retry_wait"),
            "succeeded": row.get::<_, i64>("succeeded"),
            "failed": row.get::<_, i64>("failed"),
            "canceled": row.get::<_, i64>("canceled")
        });
        for key in ["queued", "running", "judging", "retry_wait", "succeeded", "failed", "canceled"] {
            let next = counts.get(key).and_then(Value::as_i64).unwrap_or(0) + status_counts.get(key).and_then(Value::as_i64).unwrap_or(0);
            counts.insert(key.to_string(), json!(next));
        }
        let queue_total = row.get::<_, i64>("total");
        let unread_terminal = row.get::<_, i64>("unread_terminal");
        total += queue_total;
        unread_terminal_total += unread_terminal;
        queues.push(json!({
            "id": id,
            "name": row.get::<_, String>("name"),
            "total": queue_total,
            "counts": status_counts,
            "unreadTerminal": unread_terminal,
            "activeTaskId": row.get::<_, Option<String>>("active_task_id"),
            "runnableTaskId": row.get::<_, Option<String>>("runnable_task_id"),
            "processing": false,
            "createdAt": row.get::<_, Option<String>>("created_at"),
            "updatedAt": row.get::<_, Option<String>>("updated_at")
        }));
    }
    let active_rows = client
        .query(
            "
            SELECT id, queue_id, status, provider_id, execution_mode, model, cwd, prompt, base_prompt,
              reference_task_ids, reference_injection, reasoning_effort, max_attempts, current_attempt,
              current_mode, codex_thread_id, active_turn_id,
              to_json(created_at)#>>'{}' AS created_at,
              to_json(updated_at)#>>'{}' AS updated_at,
              to_json(started_at)#>>'{}' AS started_at,
              to_json(finished_at)#>>'{}' AS finished_at,
              to_json(read_at)#>>'{}' AS read_at,
              last_error, last_judge, output_count, event_count, attempt_count, last_output_seq,
              task_json - 'output' - 'events' - 'promptHistory' AS task_json
            FROM unidesk_code_queue_tasks
            WHERE status IN ('running', 'judging')
            ORDER BY updated_at DESC, id ASC
            ",
            &[],
        )
        .map_err(|error| error.to_string())?;
    let active_tasks: Vec<TaskMeta> = active_rows.iter().map(|row| row_to_task(row, true)).collect();
    let mut database_active_task_ids: Vec<String> = active_tasks.iter().map(|task| task.id.clone()).collect();
    database_active_task_ids.sort();
    let database_active_task_count = database_active_task_ids.len();
    let execution_diagnostics = execution_diagnostics_from_tasks(&active_tasks, &now_iso());
    if !queues.iter().any(|queue| queue.get("id").and_then(Value::as_str) == Some(DEFAULT_QUEUE_ID)) {
        let now = now_iso();
        queues.insert(0, json!({
            "id": DEFAULT_QUEUE_ID,
            "name": DEFAULT_QUEUE_ID,
            "total": 0,
            "counts": {},
            "unreadTerminal": 0,
            "activeTaskId": Value::Null,
            "runnableTaskId": Value::Null,
            "processing": false,
            "createdAt": now,
            "updatedAt": now
        }));
    }
    let codex_models: Vec<String> = state.config.code_models.iter().filter(|model| code_agent_port(model) == "codex").cloned().collect();
    let opencode_models: Vec<String> = state.config.code_models.iter().filter(|model| code_agent_port(model) == "opencode").cloned().collect();
    let model_ports: Map<String, Value> = state
        .config
        .code_models
        .iter()
        .map(|model| (model.clone(), json!(code_agent_port(model))))
        .collect();
    Ok(json!({
        "total": total,
        "defaultQueueId": DEFAULT_QUEUE_ID,
        "queueCount": queues.len(),
        "queues": queues,
        "activeQueueIds": [],
        "processingQueueIds": [],
        "activeRunSlotCount": 0,
        "activeRunSlotWaiters": [],
        "activeTaskIds": [],
        "activeTaskId": Value::Null,
        "databaseActiveTaskIds": database_active_task_ids,
        "databaseActiveTaskCount": database_active_task_count,
        "executionStateSource": "postgres-control-plane",
        "executionDiagnostics": execution_diagnostics,
        "schedulerHeartbeatStaleMs": SCHEDULER_HEARTBEAT_STALE_MS,
        "orphanedActiveTaskIds": [],
        "orphanedActiveTaskCount": 0,
        "processing": false,
        "counts": Value::Object(counts),
        "unreadTerminal": unread_terminal_total,
        "judgeConfigured": Value::Null,
        "judgeFailRetryLimit": 3,
        "defaultModel": state.config.default_model,
        "codeModels": state.config.code_models,
        "codexModels": codex_models,
        "opencodeModels": opencode_models,
        "modelPorts": Value::Object(model_ports),
        "executionModes": [execution_mode_info("default"), execution_mode_info("windows-native")],
        "executionModeInfo": { "default": execution_mode_info("default"), "windows-native": execution_mode_info("windows-native") },
        "agentPorts": { "codex": code_agent_port_info("codex"), "opencode": code_agent_port_info("opencode") },
        "defaultReasoningEffort": state.config.default_reasoning_effort,
        "modelReasoningEfforts": state.config.model_reasoning_efforts,
        "defaultProviderId": state.config.default_provider_id,
        "mainProviderId": state.config.default_provider_id,
        "defaultWorkdir": state.config.default_workdir,
        "remoteDefaultWorkdir": state.config.remote_default_workdir,
        "maxActiveQueues": Value::Null,
        "storage": {
            "primary": "postgres",
            "postgresConfigured": true,
            "postgresReady": schema_ready(state),
            "lastError": last_database_error(state),
            "role": "master-control-plane",
            "mgrPoolMax": state.config.mgr_pool_max,
            "tracePoolMax": state.config.trace_pool_max,
            "runtime": "rust"
        },
        "controlPlane": "master-code-queue-mgr"
    }))
}

fn create_queue(state: &AppState, request: &mut Request) -> Result<(Value, u16), (Value, u16)> {
    let body = read_json_body(request)?;
    let id_value = body.get("queueId").or_else(|| body.get("id")).and_then(Value::as_str).unwrap_or(DEFAULT_QUEUE_ID);
    let queue_id = validate_queue_id(id_value).map_err(|error| (json!({ "ok": false, "error": error }), 400))?;
    let name = queue_name_from_value(body.get("name"), &queue_id).map_err(|error| (json!({ "ok": false, "error": error }), 400))?;
    let now = now_iso();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-create-queue").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    client
        .execute(
            "
            INSERT INTO unidesk_code_queue_queues (id, name, created_at, updated_at)
            VALUES ($1, $2, $3::text::timestamptz, $3::text::timestamptz)
            ON CONFLICT (id) DO UPDATE SET name = EXCLUDED.name, updated_at = GREATEST(unidesk_code_queue_queues.updated_at, EXCLUDED.updated_at)
            ",
            &[&queue_id, &name, &now],
        )
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let queues = summary.get("queues").cloned().unwrap_or_else(|| json!([]));
    Ok((json!({ "ok": true, "queue": { "id": queue_id, "name": name, "createdAt": now, "updatedAt": now }, "queues": queues, "summary": summary }), 201))
}

fn update_queue(state: &AppState, queue_id_value: &str, request: &mut Request) -> Result<(Value, u16), (Value, u16)> {
    let body = read_json_body(request)?;
    let queue_id = validate_queue_id(queue_id_value).map_err(|error| (json!({ "ok": false, "error": error }), 400))?;
    let name = queue_name_from_value(body.get("name"), &queue_id).map_err(|error| (json!({ "ok": false, "error": error }), 400))?;
    let now = now_iso();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-update-queue").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let rows = client
        .query(
            "
            UPDATE unidesk_code_queue_queues
            SET name = $2, updated_at = $3::text::timestamptz
            WHERE id = $1
            RETURNING id, name, to_json(created_at)#>>'{}' AS created_at, to_json(updated_at)#>>'{}' AS updated_at
            ",
            &[&queue_id, &name, &now],
        )
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    let Some(row) = rows.first() else {
        return Ok((json!({ "ok": false, "error": "queue not found" }), 404));
    };
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((
        json!({
            "ok": true,
            "queue": {
                "id": row.get::<_, String>("id"),
                "name": row.get::<_, String>("name"),
                "createdAt": row.get::<_, String>("created_at"),
                "updatedAt": row.get::<_, String>("updated_at")
            },
            "summary": summary,
            "queues": summary.get("queues").cloned().unwrap_or_else(|| json!([]))
        }),
        200,
    ))
}

fn default_workdir_record(state: &AppState, timestamp: &str) -> Result<Value, String> {
    let provider_id = normalize_workdir_provider_id(state, &state.config.default_provider_id);
    let path = normalize_workdir_path(state, &provider_id, &state.config.default_workdir)?;
    Ok(json!({
        "providerId": provider_id,
        "executionMode": "default",
        "path": path,
        "createdAt": timestamp,
        "updatedAt": timestamp
    }))
}

fn workdir_key(record: &Value) -> String {
    format!(
        "{}\u{0}{}\u{0}{}",
        record.get("providerId").and_then(Value::as_str).unwrap_or(""),
        record.get("executionMode").and_then(Value::as_str).unwrap_or("default"),
        record.get("path").and_then(Value::as_str).unwrap_or("")
    )
}

fn sorted_workdir_records(records: Vec<Value>) -> Vec<Value> {
    let mut keyed = std::collections::BTreeMap::<String, Value>::new();
    for record in records {
        keyed.insert(workdir_key(&record), record);
    }
    keyed.into_values().collect()
}

fn upsert_default_workdir(client: &mut Client, state: &AppState, timestamp: &str) -> Result<(), String> {
    let record = default_workdir_record(state, timestamp)?;
    let provider_id = record.get("providerId").and_then(Value::as_str).unwrap_or("").to_string();
    let execution_mode = record.get("executionMode").and_then(Value::as_str).unwrap_or("default").to_string();
    let path = record.get("path").and_then(Value::as_str).unwrap_or("").to_string();
    client
        .execute(
            "
            INSERT INTO unidesk_code_queue_workdirs (provider_id, execution_mode, path, created_at, updated_at)
            VALUES ($1, $2, $3, $4::text::timestamptz, $4::text::timestamptz)
            ON CONFLICT (provider_id, execution_mode, path) DO UPDATE SET updated_at = EXCLUDED.updated_at
            ",
            &[&provider_id, &execution_mode, &path, &timestamp],
        )
        .map_err(|error| error_detail(&error))?;
    Ok(())
}

fn load_workdirs(state: &AppState) -> Result<Vec<Value>, String> {
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-workdirs")?;
    let rows = client
        .query(
            "
            SELECT provider_id, execution_mode, path, created_at::text, updated_at::text
            FROM unidesk_code_queue_workdirs
            ORDER BY provider_id ASC, execution_mode ASC, path ASC
            ",
            &[],
        )
        .map_err(|error| error_detail(&error))?;
    let mut records = Vec::new();
    if let Ok(record) = default_workdir_record(state, &now_iso()) {
        records.push(record);
    }
    for row in rows {
        let provider_id = normalize_workdir_provider_id(state, row.get::<_, &str>(0));
        let execution_mode_raw: &str = row.get(1);
        let execution_mode = match execution_mode_raw {
            "windows-native" => "windows-native",
            _ => "default",
        };
        let path_raw: &str = row.get(2);
        let path = normalize_workdir_path(state, &provider_id, path_raw)?;
        records.push(json!({
            "providerId": provider_id,
            "executionMode": execution_mode,
            "path": path,
            "createdAt": row.get::<_, String>(3),
            "updatedAt": row.get::<_, String>(4)
        }));
    }
    Ok(sorted_workdir_records(records))
}

fn list_workdirs(state: &AppState, url: &RequestUrl) -> Result<(Value, u16), (Value, u16)> {
    let provider_filter = query_param(url, "providerId")
        .filter(|value| !value.trim().is_empty())
        .map(|value| normalize_workdir_provider_id(state, &value));
    let mode_filter = query_param(url, "executionMode")
        .filter(|value| !value.trim().is_empty())
        .map(|value| normalize_execution_mode(Some(&json!(value))));
    let records = load_workdirs(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let workdirs = records
        .into_iter()
        .filter(|record| {
            if let Some(provider_id) = &provider_filter {
                if record.get("providerId").and_then(Value::as_str) != Some(provider_id.as_str()) {
                    return false;
                }
            }
            if let Some(mode) = &mode_filter {
                if record.get("executionMode").and_then(Value::as_str) != Some(mode.as_str()) {
                    return false;
                }
            }
            true
        })
        .collect::<Vec<_>>();
    Ok((json!({
        "ok": true,
        "workdirs": workdirs,
        "defaultProviderId": state.config.default_provider_id,
        "defaultWorkdir": state.config.default_workdir,
        "remoteDefaultWorkdir": state.config.remote_default_workdir,
        "source": "code-queue-mgr-rust-postgres"
    }), 200))
}

fn create_workdir(state: &AppState, request: &mut Request) -> Result<(Value, u16), (Value, u16)> {
    let body = read_json_body(request)?;
    let provider_id = normalize_workdir_provider_id(state, body.get("providerId").and_then(Value::as_str).unwrap_or(""));
    let execution_mode = normalize_execution_mode(body.get("executionMode"));
    let raw_path = body
        .get("path")
        .or_else(|| body.get("cwd"))
        .or_else(|| body.get("workdir"))
        .and_then(Value::as_str)
        .unwrap_or("");
    let path = normalize_workdir_path(state, &provider_id, raw_path).map_err(|error| (json!({ "ok": false, "error": error }), 400))?;
    let now = now_iso();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-workdir-create").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    client
        .execute(
            "
            INSERT INTO unidesk_code_queue_workdirs (provider_id, execution_mode, path, created_at, updated_at)
            VALUES ($1, $2, $3, $4::text::timestamptz, $4::text::timestamptz)
            ON CONFLICT (provider_id, execution_mode, path) DO UPDATE SET updated_at = EXCLUDED.updated_at
            ",
            &[&provider_id, &execution_mode, &path, &now],
        )
        .map_err(|error| (json!({ "ok": false, "error": error_detail(&error) }), 500))?;
    let workdir = json!({ "providerId": provider_id, "executionMode": execution_mode, "path": path, "createdAt": now, "updatedAt": now });
    let workdirs = load_workdirs(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((json!({
        "ok": true,
        "workdir": workdir,
        "workdirs": workdirs,
        "ensure": { "ok": true, "skipped": true, "reason": "code-queue-mgr records workdir menu options only; provider directories are created by the execution plane" }
    }), 201))
}

fn delete_workdir(state: &AppState, provider_id_value: &str, execution_mode_value: &str, path_value: &str) -> Result<(Value, u16), (Value, u16)> {
    let provider_id = normalize_workdir_provider_id(state, provider_id_value);
    let execution_mode = normalize_execution_mode(Some(&json!(execution_mode_value)));
    let path = normalize_workdir_path(state, &provider_id, path_value).map_err(|error| (json!({ "ok": false, "error": error }), 400))?;
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-workdir-delete").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let rows = client
        .query(
            "
            DELETE FROM unidesk_code_queue_workdirs
            WHERE provider_id = $1 AND execution_mode = $2 AND path = $3
            RETURNING provider_id, execution_mode, path, created_at::text, updated_at::text
            ",
            &[&provider_id, &execution_mode, &path],
        )
        .map_err(|error| (json!({ "ok": false, "error": error_detail(&error) }), 500))?;
    let Some(row) = rows.first() else {
        return Ok((json!({ "ok": false, "error": "workdir not found" }), 404));
    };
    let deleted = json!({
        "providerId": row.get::<_, String>(0),
        "executionMode": row.get::<_, String>(1),
        "path": row.get::<_, String>(2),
        "createdAt": row.get::<_, String>(3),
        "updatedAt": row.get::<_, String>(4)
    });
    let workdirs = load_workdirs(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((json!({ "ok": true, "deleted": deleted, "workdirs": workdirs }), 200))
}

fn normalize_provider_id(state: &AppState, value: Option<&Value>) -> String {
    value
        .and_then(Value::as_str)
        .map(str::trim)
        .filter(|text| !text.is_empty())
        .unwrap_or(&state.config.default_provider_id)
        .to_string()
}

fn normalize_workdir_provider_id(state: &AppState, value: &str) -> String {
    let text = value.trim();
    if !text.is_empty()
        && text.len() <= 64
        && text
            .chars()
            .all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '_' | '.' | '-'))
    {
        text.to_string()
    } else {
        state.config.default_provider_id.clone()
    }
}

fn normalize_cwd(state: &AppState, provider_id: &str, value: Option<&Value>) -> String {
    value
        .and_then(Value::as_str)
        .map(str::trim)
        .filter(|text| !text.is_empty())
        .map(ToString::to_string)
        .unwrap_or_else(|| if provider_id == "main-server" { state.config.default_workdir.clone() } else { state.config.remote_default_workdir.clone() })
}

fn default_workdir_for_provider(state: &AppState, provider_id: &str) -> String {
    if provider_id == state.config.default_provider_id {
        state.config.default_workdir.clone()
    } else {
        state.config.remote_default_workdir.clone()
    }
}

fn normalize_workdir_path(state: &AppState, provider_id: &str, value: &str) -> Result<String, String> {
    let raw = value.trim();
    if raw.is_empty() {
        return Err("workdir path is required".to_string());
    }
    if raw.chars().count() > WORKDIR_MAX_CHARS {
        return Err(format!("workdir path must be {WORKDIR_MAX_CHARS} characters or fewer"));
    }
    if raw.contains('\0') {
        return Err("workdir path contains an invalid character".to_string());
    }
    let path = if raw.starts_with('/') {
        raw.to_string()
    } else {
        format!("{}/{}", default_workdir_for_provider(state, provider_id).trim_end_matches('/'), raw)
    };
    let trimmed = path.trim_end_matches('/').to_string();
    Ok(if trimmed.is_empty() { "/".to_string() } else { trimmed })
}

fn normalize_execution_mode(value: Option<&Value>) -> String {
    match value.and_then(Value::as_str).unwrap_or("").trim().to_ascii_lowercase().as_str() {
        "windows-native" | "windows" | "win32" | "native-windows" => "windows-native".to_string(),
        _ => "default".to_string(),
    }
}

fn collect_reference_ids(value: Option<&Value>) -> Vec<String> {
    match value {
        Some(Value::String(item)) => item.split([',', ' ', '\n', '\t', ';']).map(str::trim).filter(|item| !item.is_empty()).map(ToString::to_string).collect(),
        Some(Value::Array(items)) => items.iter().filter_map(Value::as_str).map(str::trim).filter(|item| !item.is_empty()).map(ToString::to_string).collect(),
        _ => Vec::new(),
    }
}

fn make_task_id() -> String {
    format!("codex_{}_{}", Utc::now().timestamp_millis(), std::process::id())
}

fn create_single_task_json(state: &AppState, item: &Value, queue_override: Option<&str>) -> Result<(String, String, Value), String> {
    let record = item.as_object().ok_or_else(|| "request body must be an object".to_string())?;
    let raw_prompt = record.get("prompt").and_then(Value::as_str).ok_or_else(|| "prompt is required".to_string())?;
    if raw_prompt.trim().is_empty() {
        return Err("prompt is required".to_string());
    }
    let base_prompt = record.get("basePrompt").and_then(Value::as_str).filter(|value| !value.is_empty()).map(ToString::to_string).unwrap_or_else(|| user_prompt_for_display(raw_prompt));
    let prompt = prompt_with_environment_hint(raw_prompt);
    let queue_id = validate_queue_id(queue_override.or_else(|| record.get("queueId").and_then(Value::as_str)).unwrap_or(DEFAULT_QUEUE_ID))?;
    let provider_id = normalize_provider_id(state, record.get("providerId"));
    let cwd = normalize_cwd(state, &provider_id, record.get("cwd"));
    let model = normalize_code_model(record.get("model").and_then(Value::as_str).unwrap_or(&state.config.default_model));
    let reasoning_effort = record
        .get("reasoningEffort")
        .and_then(Value::as_str)
        .map(ToString::to_string)
        .or_else(|| state.config.model_reasoning_efforts.get(model.to_ascii_lowercase()).and_then(Value::as_str).map(ToString::to_string))
        .or_else(|| state.config.default_reasoning_effort.clone());
    let max_attempts = record.get("maxAttempts").and_then(Value::as_i64).unwrap_or(state.config.default_max_attempts).clamp(1, 99);
    let execution_mode = normalize_execution_mode(record.get("executionMode"));
    let reference_task_ids = collect_reference_ids(record.get("referenceTaskIds").or_else(|| record.get("referenceTaskId")));
    let at = now_iso();
    let task_id = make_task_id();
    let task = json!({
        "id": task_id,
        "queueId": queue_id,
        "queueEnteredAt": at,
        "prompt": prompt,
        "basePrompt": base_prompt,
        "referenceTaskIds": reference_task_ids,
        "referenceInjection": Value::Null,
        "providerId": provider_id,
        "cwd": cwd,
        "model": model,
        "reasoningEffort": reasoning_effort,
        "executionMode": execution_mode,
        "maxAttempts": max_attempts,
        "status": "queued",
        "createdAt": at,
        "updatedAt": at,
        "startedAt": Value::Null,
        "finishedAt": Value::Null,
        "readAt": Value::Null,
        "currentAttempt": 0,
        "currentMode": Value::Null,
        "codexThreadId": Value::Null,
        "activeTurnId": Value::Null,
        "finalResponse": "",
        "stepCount": 0,
        "llmStepCount": 0,
        "outputMaxSeq": 1,
        "lastError": Value::Null,
        "lastJudge": Value::Null,
        "judgeFailCount": 0,
        "promptHistory": [],
        "output": [{ "seq": 1, "at": at, "channel": "user", "text": format!("{prompt}\n"), "method": "enqueue" }],
        "events": [],
        "attempts": [],
        "cancelRequested": false,
        "nextPrompt": Value::Null,
        "nextMode": Value::Null
    });
    Ok((task_id, queue_id, task))
}

fn create_tasks(state: &AppState, request: &mut Request) -> Result<(Value, u16), (Value, u16)> {
    let body = read_json_body(request)?;
    let queue_override = body.get("queueId").and_then(Value::as_str).map(ToString::to_string);
    let raw_tasks: Vec<Value> = body
        .get("tasks")
        .and_then(Value::as_array)
        .cloned()
        .unwrap_or_else(|| vec![body.clone()]);
    let mut prepared = Vec::new();
    for item in raw_tasks {
        prepared.push(create_single_task_json(state, &item, queue_override.as_deref()).map_err(|error| (json!({ "ok": false, "error": error }), 400))?);
    }
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-create-tasks").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let mut transaction = client.transaction().map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    for (_task_id, queue_id, task) in &prepared {
        let now = task.get("createdAt").and_then(Value::as_str).unwrap_or_else(|| "");
        transaction
            .execute(
                "
                INSERT INTO unidesk_code_queue_queues (id, name, created_at, updated_at)
                VALUES ($1, $1, $2::text::timestamptz, $2::text::timestamptz)
                ON CONFLICT (id) DO UPDATE SET updated_at = GREATEST(unidesk_code_queue_queues.updated_at, EXCLUDED.updated_at)
                ",
                &[queue_id, &now],
            )
            .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
        let reference_task_ids = task.get("referenceTaskIds").cloned().unwrap_or_else(|| json!([]));
        let reference_injection: Option<Value> = None;
        let reasoning_effort: Option<String> = task.get("reasoningEffort").and_then(Value::as_str).map(ToString::to_string);
        let current_mode: Option<String> = None;
        let codex_thread_id: Option<String> = None;
        let active_turn_id: Option<String> = None;
        let started_at: Option<String> = None;
        let finished_at: Option<String> = None;
        let read_at: Option<String> = None;
        let last_error: Option<String> = None;
        let last_judge: Option<Value> = None;
        let id = task.get("id").and_then(Value::as_str).unwrap_or("");
        let status = "queued".to_string();
        let provider_id = task.get("providerId").and_then(Value::as_str).unwrap_or("D601").to_string();
        let execution_mode = task.get("executionMode").and_then(Value::as_str).unwrap_or("default").to_string();
        let model = task.get("model").and_then(Value::as_str).unwrap_or("gpt-5.5").to_string();
        let cwd = task.get("cwd").and_then(Value::as_str).unwrap_or("/home/ubuntu").to_string();
        let prompt = task.get("prompt").and_then(Value::as_str).unwrap_or("").to_string();
        let base_prompt = task.get("basePrompt").and_then(Value::as_str).unwrap_or("").to_string();
        let max_attempts = task.get("maxAttempts").and_then(Value::as_i64).unwrap_or(99) as i32;
        let current_attempt = 0_i32;
        transaction
            .execute(
                "
                INSERT INTO unidesk_code_queue_tasks (
                  id, queue_id, status, provider_id, execution_mode, model, cwd, prompt, base_prompt,
                  reference_task_ids, reference_injection, reasoning_effort, max_attempts,
                  current_attempt, current_mode, codex_thread_id, active_turn_id,
                  created_at, updated_at, started_at, finished_at, read_at, last_error,
                  last_judge, output_count, event_count, attempt_count, last_output_seq, task_json
                ) VALUES (
                  $1, $2, $3, $4, $5, $6, $7, $8, $9,
                  $10, $11, $12, $13,
                  $14, $15, $16, $17,
                  $18::text::timestamptz, $19::text::timestamptz, $20::text::timestamptz, $21::text::timestamptz, $22::text::timestamptz, $23,
                  $24, 1, 0, 0, 1, $25
                )
                ON CONFLICT (id) DO NOTHING
                ",
                &[
                    &id,
                    queue_id,
                    &status,
                    &provider_id,
                    &execution_mode,
                    &model,
                    &cwd,
                    &prompt,
                    &base_prompt,
                    &reference_task_ids,
                    &reference_injection,
                    &reasoning_effort,
                    &max_attempts,
                    &current_attempt,
                    &current_mode,
                    &codex_thread_id,
                    &active_turn_id,
                    &now,
                    &now,
                    &started_at,
                    &finished_at,
                    &read_at,
                    &last_error,
                    &last_judge,
                    task,
                ],
            )
            .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    }
    transaction.commit().map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    let mut tasks = Vec::new();
    for (task_id, _queue_id, _task) in &prepared {
        if let Some(task) = load_task(state, task_id, true).map_err(|error| (json!({ "ok": false, "error": error }), 500))? {
            tasks.push(task_list_response(state, &task, false));
        }
    }
    log_event(state, "info", "tasks_enqueued", json!({ "ids": prepared.iter().map(|item| item.0.clone()).collect::<Vec<_>>() }));
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((json!({ "ok": true, "tasks": tasks, "queue": summary }), 202))
}

fn output_to_transcript(item: &Value, full_text: bool) -> Value {
    let channel = item.get("channel").and_then(Value::as_str).unwrap_or("system");
    let kind = match channel {
        "command" => "ran",
        "diff" => "edited",
        "tool" => "explored",
        "error" => "error",
        "system" => "system",
        _ => "message",
    };
    let text = text_from_output(item);
    let body = if full_text { text } else { preview(&text, 1600) };
    json!({
        "seq": seq_from_output(item),
        "at": item.get("at").cloned().unwrap_or_else(|| json!(now_iso())),
        "kind": kind,
        "title": item.get("method").cloned().or_else(|| item.get("channel").cloned()).unwrap_or_else(|| json!("message")),
        "status": item.get("method").cloned().unwrap_or(Value::Null),
        "commandPreview": if channel == "command" { json!(body) } else { Value::Null },
        "bodyPreview": if channel == "command" { json!("") } else { json!(body) },
        "commandOmittedLines": 0,
        "bodyOmittedLines": 0,
        "rawSeqs": [seq_from_output(item)]
    })
}

fn transcript_page(task: &TaskMeta, url: &RequestUrl) -> Value {
    let limit = parse_usize(query_param(url, "limit"), 80).clamp(1, MAX_OUTPUT_PAGE_LIMIT);
    let after_seq = parse_i64(query_param(url, "afterSeq"), 0);
    let before_seq = query_param(url, "beforeSeq").and_then(|value| value.parse::<i64>().ok());
    let tail = query_param(url, "tail").as_deref() == Some("1");
    let full_text = query_param(url, "fullText").as_deref() == Some("1") || query_param(url, "raw").as_deref() == Some("1");
    let mut rows: Vec<Value> = output_array(task)
        .into_iter()
        .filter(|item| !(item.get("channel").and_then(Value::as_str) == Some("system") && item.get("method").and_then(Value::as_str) == Some("enqueue")))
        .collect();
    rows.sort_by_key(seq_from_output);
    let total = rows.len();
    let selected: Vec<Value> = if let Some(before) = before_seq {
        let mut items: Vec<Value> = rows.into_iter().filter(|item| seq_from_output(item) < before).collect();
        if items.len() > limit {
            items = items[items.len() - limit..].to_vec();
        }
        items
    } else if tail {
        if rows.len() > limit { rows[rows.len() - limit..].to_vec() } else { rows }
    } else {
        rows.into_iter().filter(|item| seq_from_output(item) > after_seq).take(limit).collect()
    };
    let first_seq = selected.first().map(seq_from_output);
    let last_seq = selected.last().map(seq_from_output);
    let max_seq = output_max_seq(task);
    json!({
        "ok": true,
        "taskId": task.id,
        "queueId": task.queue_id,
        "status": task.status,
        "updatedAt": task.updated_at,
        "agentPort": code_agent_port(&task.model),
        "agentPortInfo": code_agent_port_info(code_agent_port(&task.model)),
        "mode": if before_seq.is_some() { "before" } else if tail { "tail" } else { "after" },
        "transcript": selected.iter().map(|item| output_to_transcript(item, full_text)).collect::<Vec<_>>(),
        "afterSeq": after_seq,
        "nextAfterSeq": last_seq.unwrap_or(after_seq),
        "beforeSeq": before_seq,
        "previousBeforeSeq": first_seq,
        "hasMore": last_seq.map(|seq| seq < max_seq).unwrap_or(false),
        "hasBefore": first_seq.map(|seq| seq > 1).unwrap_or(false),
        "total": total,
        "maxSeq": max_seq,
        "fullText": full_text
    })
}

fn output_page(task: &TaskMeta, url: &RequestUrl) -> Value {
    let limit = parse_usize(query_param(url, "limit"), 80).clamp(1, MAX_OUTPUT_PAGE_LIMIT);
    let after_seq = parse_i64(query_param(url, "afterSeq"), 0);
    let before_seq = query_param(url, "beforeSeq").and_then(|value| value.parse::<i64>().ok());
    let tail = query_param(url, "tail").as_deref() == Some("1");
    let full_text = query_param(url, "fullText").as_deref() == Some("1");
    let max_chars = parse_usize(query_param(url, "maxTextChars"), MAX_PREVIEW_CHARS).clamp(200, 100_000);
    let mut rows = output_array(task);
    rows.sort_by_key(seq_from_output);
    let total = rows.len();
    let selected: Vec<Value> = if let Some(before) = before_seq {
        let mut items: Vec<Value> = rows.into_iter().filter(|item| seq_from_output(item) < before).collect();
        if items.len() > limit {
            items = items[items.len() - limit..].to_vec();
        }
        items
    } else if tail {
        if rows.len() > limit { rows[rows.len() - limit..].to_vec() } else { rows }
    } else {
        rows.into_iter().filter(|item| seq_from_output(item) > after_seq).take(limit).collect()
    };
    let first_seq = selected.first().map(seq_from_output);
    let last_seq = selected.last().map(seq_from_output);
    let output = selected
        .iter()
        .map(|item| {
            let mut next = item.clone();
            if !full_text {
                if let Some(map) = next.as_object_mut() {
                    let text = map.get("text").and_then(Value::as_str).unwrap_or("");
                    map.insert("text".to_string(), json!(preview(text, max_chars)));
                }
            }
            next
        })
        .collect::<Vec<_>>();
    let max_seq = output_max_seq(task);
    json!({
        "ok": true,
        "taskId": task.id,
        "queueId": task.queue_id,
        "status": task.status,
        "updatedAt": task.updated_at,
        "mode": if before_seq.is_some() { "before" } else if tail { "tail" } else { "after" },
        "limit": limit,
        "total": total,
        "maxSeq": max_seq,
        "afterSeq": after_seq,
        "nextAfterSeq": last_seq,
        "beforeSeq": before_seq,
        "previousBeforeSeq": first_seq,
        "hasMore": last_seq.map(|seq| seq < max_seq).unwrap_or(false),
        "hasBefore": first_seq.map(|seq| seq > 1).unwrap_or(false),
        "output": output
    })
}

fn trace_step_from_output(item: &Value) -> Value {
    let text = text_from_output(item);
    let channel = item.get("channel").and_then(Value::as_str).unwrap_or("system");
    let kind = match channel {
        "command" => "ran",
        "diff" => "edited",
        "tool" => "explored",
        "error" => "error",
        "system" => "system",
        _ => "message",
    };
    let body = preview(&text, 1600);
    json!({
        "seq": seq_from_output(item),
        "at": item.get("at").cloned().unwrap_or_else(|| json!(now_iso())),
        "kind": kind,
        "label": channel,
        "title": item.get("method").cloned().or_else(|| item.get("channel").cloned()).unwrap_or_else(|| json!("message")),
        "status": item.get("method").cloned().unwrap_or(Value::Null),
        "summaryLines": if body.is_empty() { json!([]) } else { json!([body]) },
        "commandPreview": if channel == "command" { json!(body) } else { Value::Null },
        "commandOmittedLines": 0,
        "bodyPreview": if channel == "command" { json!("") } else { json!(body) },
        "bodyOmittedLines": 0,
        "rawSeqs": [seq_from_output(item)],
        "source": "code-queue-mgr-rust-postgres"
    })
}

fn trace_steps(task: &TaskMeta, url: &RequestUrl) -> Value {
    let limit = parse_usize(query_param(url, "limit"), 80).clamp(1, MAX_OUTPUT_PAGE_LIMIT);
    let after_seq = parse_i64(query_param(url, "afterSeq"), 0);
    let before_seq = query_param(url, "beforeSeq").and_then(|value| value.parse::<i64>().ok());
    let tail = query_param(url, "tail").as_deref() == Some("1");
    let mut rows: Vec<Value> = output_array(task)
        .into_iter()
        .filter(|item| !(item.get("channel").and_then(Value::as_str) == Some("system") && item.get("method").and_then(Value::as_str) == Some("enqueue")))
        .map(|item| trace_step_from_output(&item))
        .collect();
    rows.sort_by_key(|item| item.get("seq").and_then(Value::as_i64).unwrap_or(0));
    let total = rows.len();
    let selected: Vec<Value> = if let Some(before) = before_seq {
        let mut items: Vec<Value> = rows.into_iter().filter(|item| item.get("seq").and_then(Value::as_i64).unwrap_or(0) < before).collect();
        if items.len() > limit {
            items = items[items.len() - limit..].to_vec();
        }
        items
    } else if tail {
        if rows.len() > limit { rows[rows.len() - limit..].to_vec() } else { rows }
    } else {
        rows.into_iter().filter(|item| item.get("seq").and_then(Value::as_i64).unwrap_or(0) > after_seq).take(limit).collect()
    };
    let first_seq = selected.first().and_then(|item| item.get("seq")).and_then(Value::as_i64);
    let last_seq = selected.last().and_then(|item| item.get("seq")).and_then(Value::as_i64);
    let max_seq = output_max_seq(task);
    json!({
        "ok": true,
        "taskId": task.id,
        "source": "code-queue-mgr-rust-postgres",
        "total": total,
        "returned": selected.len(),
        "limit": limit,
        "afterSeq": after_seq,
        "nextAfterSeq": last_seq,
        "beforeSeq": before_seq,
        "previousBeforeSeq": first_seq,
        "hasMore": last_seq.map(|seq| seq < max_seq).unwrap_or(false),
        "hasBefore": first_seq.map(|seq| seq > 1).unwrap_or(false),
        "steps": selected
    })
}

fn trace_step_detail(task: &TaskMeta, url: &RequestUrl) -> Value {
    let seq = parse_i64(query_param(url, "seq"), 0);
    let item = output_array(task).into_iter().find(|item| seq_from_output(item) == seq);
    match item {
        Some(raw) => {
            let line = trace_step_from_output(&raw);
            json!({ "ok": true, "taskId": task.id, "source": "code-queue-mgr-rust-postgres", "step": line, "rawOutput": raw, "line": line })
        }
        None => json!({ "ok": false, "error": "trace step not found" }),
    }
}

fn task_summary(task: &TaskMeta) -> Value {
    let outputs = output_array(task);
    let trace_outputs = trace_countable_outputs(task);
    let tool_outputs: Vec<Value> = outputs
        .iter()
        .filter(|item| matches!(item.get("channel").and_then(Value::as_str), Some("command" | "tool" | "diff" | "error")))
        .cloned()
        .collect();
    let start = tool_outputs.len().saturating_sub(160);
    let tool_items = tool_outputs[start..]
        .iter()
        .map(|item| {
            let channel = item.get("channel").and_then(Value::as_str).unwrap_or("");
            json!({
                "seq": seq_from_output(item),
                "at": item.get("at").cloned().unwrap_or(Value::Null),
                "kind": if channel == "diff" { "edited" } else if channel == "command" { "ran" } else if channel == "tool" { "explored" } else { "error" },
                "title": item.get("method").cloned().or_else(|| item.get("channel").cloned()).unwrap_or(Value::Null),
                "status": item.get("method").cloned().unwrap_or(Value::Null),
                "commandPreview": if channel == "command" { json!(preview(&text_from_output(item), 700)) } else { json!("") },
                "commandOmittedLines": 0,
                "outputPreview": if channel == "command" { json!("") } else { json!(preview(&text_from_output(item), 1200)) },
                "outputOmittedLines": 0,
                "rawSeqs": [seq_from_output(item)]
            })
        })
        .collect::<Vec<_>>();
    let agent_port = code_agent_port(&task.model);
    let raw_step_count = raw_trace_step_count(task);
    let execution = trace_execution_contract(&format!("task:{}", task.id), raw_step_count, output_max_seq(task));
    let trace_stats = execution.get("traceStats").cloned().unwrap_or(Value::Null);
    let attempts = attempt_indexes_for_trace(task, &trace_outputs)
        .into_iter()
        .map(|index| attempt_trace_window(task, &trace_outputs, index))
        .collect::<Vec<_>>();
    json!({
        "id": task.id,
        "queueId": task.queue_id,
        "status": task.status,
        "providerId": task.provider_id,
        "executionMode": task.execution_mode,
        "executionModeInfo": execution_mode_info(&task.execution_mode),
        "model": task.model,
        "agentPort": agent_port,
        "agentPortInfo": code_agent_port_info(agent_port),
        "cwd": task.cwd,
        "reasoningEffort": task.reasoning_effort,
        "maxAttempts": task.max_attempts,
        "currentAttempt": task.current_attempt,
        "currentMode": task.current_mode,
        "judgeFailCount": task.task_json.as_ref().and_then(|value| value.get("judgeFailCount")).and_then(Value::as_i64).unwrap_or(0),
        "judgeFailRetryLimit": 3,
        "schedulerHeartbeat": task_scheduler_heartbeat(task).unwrap_or(Value::Null),
        "codexThreadId": task.codex_thread_id,
        "activeTurnId": task.active_turn_id,
        "createdAt": task.created_at,
        "startedAt": task.started_at,
        "finishedAt": task.finished_at,
        "updatedAt": task.updated_at,
        "timing": timing_json(task),
        "initialPrompt": task.prompt,
        "basePrompt": task.base_prompt,
        "prompt": task.prompt,
        "promptEditable": queued_prompt_editable(task),
        "referenceTaskIds": task.reference_task_ids,
        "referenceInjection": task.reference_injection,
        "lastAssistantMessage": last_assistant_message(task),
        "toolSummary": { "count": tool_outputs.len(), "returned": tool_outputs.len().saturating_sub(start), "limit": 160, "truncated": start > 0, "items": tool_items },
        "attempts": attempts,
        "lastJudge": task.last_judge,
        "lastError": task.last_error,
        "cancelRequested": task.task_json.as_ref().and_then(|value| value.get("cancelRequested")).and_then(Value::as_bool).unwrap_or(false),
        "outputCount": outputs.len(),
        "eventCount": json_array_len(task.task_json.as_ref(), "events", task.event_count),
        "transcriptCount": outputs.len() + json_array_len(task.task_json.as_ref(), "promptHistory", 0) as usize,
        "transcriptMaxSeq": output_max_seq(task),
        "finalResponse": final_response(task),
        "stepCount": raw_step_count,
        "llmStepCount": task.task_json.as_ref().and_then(|value| value.get("llmStepCount")).and_then(Value::as_i64).unwrap_or(task.last_output_seq),
        "traceStats": trace_stats,
        "statsSource": execution.get("statsSource").cloned().unwrap_or_else(|| json!("raw-trace-empty")),
        "traceStatsState": execution.get("traceStatsState").cloned().unwrap_or_else(|| json!("empty")),
        "traceStatsReason": execution.get("traceStatsReason").cloned().unwrap_or_else(|| json!("no-trace-steps-yet")),
        "statsUnavailable": true,
        "statsSyncing": raw_step_count > 0,
        "rawTraceStepCount": raw_step_count,
        "execution": execution
    })
}

fn trace_summary(task: &TaskMeta) -> Value {
    let outputs = trace_countable_outputs(task);
    let step_count = raw_trace_step_count(task);
    let output_max_seq = output_max_seq(task);
    let execution = trace_execution_contract(&format!("task:{}", task.id), step_count, output_max_seq);
    let trace_stats = execution.get("traceStats").cloned().unwrap_or(Value::Null);
    let attempts = attempt_indexes_for_trace(task, &outputs)
        .into_iter()
        .map(|index| attempt_trace_window(task, &outputs, index))
        .collect::<Vec<_>>();
    json!({
        "id": task.id,
        "taskId": task.id,
        "queueId": task.queue_id,
        "status": task.status,
        "providerId": task.provider_id,
        "executionMode": task.execution_mode,
        "executionModeInfo": execution_mode_info(&task.execution_mode),
        "model": task.model,
        "cwd": task.cwd,
        "reasoningEffort": task.reasoning_effort,
        "stepCount": step_count,
        "llmStepCount": 0,
        "toolCallCount": step_count,
        "editedFileCount": 0,
        "commandCount": 0,
        "retainedStepCount": outputs.len(),
        "outputMaxSeq": output_max_seq,
        "schedulerHeartbeat": task_scheduler_heartbeat(task).unwrap_or(Value::Null),
        "traceStats": trace_stats,
        "statsSource": execution.get("statsSource").cloned().unwrap_or_else(|| json!("raw-trace-empty")),
        "traceStatsState": execution.get("traceStatsState").cloned().unwrap_or_else(|| json!("empty")),
        "traceStatsReason": execution.get("traceStatsReason").cloned().unwrap_or_else(|| json!("no-trace-steps-yet")),
        "statsUnavailable": true,
        "statsSyncing": step_count > 0,
        "rawTraceStepCount": step_count,
        "execution": execution,
        "attempts": attempts,
        "prompt": { "initialPreview": preview(&task.prompt, 1600), "basePreview": preview(&task.base_prompt, 1600), "chars": task.prompt.chars().count(), "lines": task.prompt.lines().count() },
        "lastAssistantMessage": last_assistant_message(task),
        "createdAt": task.created_at,
        "updatedAt": task.updated_at,
        "finalResponse": final_response(task),
        "lastJudge": task.last_judge,
        "lastError": task.last_error,
        "currentAttempt": task.current_attempt,
        "currentMode": task.current_mode,
        "maxAttempts": task.max_attempts,
        "startedAt": task.started_at,
        "finishedAt": task.finished_at,
        "timing": timing_json(task)
    })
}

fn tasks_overview(state: &AppState, url: &RequestUrl) -> Result<(Value, u16), (Value, u16)> {
    let selected_enabled = query_param(url, "selected").as_deref() != Some("0");
    let prefer_id = query_param(url, "preferId").unwrap_or_default();
    let include_selected_json = selected_enabled && !prefer_id.is_empty();
    let include_statistics = query_param(url, "stats").as_deref() != Some("0");
    let (tasks, total, limit, offset) = load_tasks_for_list(state, url, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let statistics = if include_statistics {
        task_statistics_summary(state, codex_stats_queue_id_from_url(url), codex_stats_days_from_url(url))
            .map_err(|error| (json!({ "ok": false, "error": error }), 500))?
    } else {
        Value::Null
    };
    let selected = if include_selected_json {
        let selected_id = if prefer_id.is_empty() { tasks.first().map(|task| task.id.clone()).unwrap_or_default() } else { prefer_id };
        if selected_id.is_empty() {
            Value::Null
        } else if let Some(task) = load_task(state, &selected_id, true).map_err(|error| (json!({ "ok": false, "error": error }), 500))? {
            let transcript_limit = parse_usize(query_param(url, "transcriptLimit"), 80).clamp(1, MAX_OUTPUT_PAGE_LIMIT);
            let after_seq = parse_i64(query_param(url, "afterSeq"), 0);
            let mut output = output_array(&task);
            output.sort_by_key(seq_from_output);
            let rows = output.into_iter().filter(|item| seq_from_output(item) > after_seq).take(transcript_limit).map(|item| {
                json!({
                    "seq": seq_from_output(&item),
                    "at": item.get("at").cloned().unwrap_or(Value::Null),
                    "kind": output_to_transcript(&item, false).get("kind").cloned().unwrap_or_else(|| json!("message")),
                    "title": item.get("method").cloned().or_else(|| item.get("channel").cloned()).unwrap_or(Value::Null),
                    "status": item.get("method").cloned().unwrap_or(Value::Null),
                    "bodyPreview": preview(&text_from_output(&item), 1200),
                    "rawSeqs": [seq_from_output(&item)]
                })
            }).collect::<Vec<_>>();
            json!({
                "task": task_meta_response(state, &task),
                "transcript": rows,
                "afterSeq": after_seq,
                "nextAfterSeq": output_max_seq(&task),
                "hasMore": false,
                "preview": true,
                "total": json_array_len(task.task_json.as_ref(), "output", task.output_count),
                "maxSeq": output_max_seq(&task)
            })
        } else {
            Value::Null
        }
    } else {
        Value::Null
    };
    Ok((
        json!({
            "ok": true,
            "queue": summary,
            "statistics": statistics,
            "tasks": tasks.iter().map(|task| task_list_response(state, task, true)).collect::<Vec<_>>(),
            "selected": selected,
            "pagination": {
                "limit": limit,
                "returned": tasks.len(),
                "total": total,
                "hasMore": (offset + tasks.len() as i64) < total,
                "nextBeforeId": Value::Null,
                "beforeId": Value::Null,
                "includeActive": false
            }
        }),
        200,
    ))
}

fn mark_task_read(state: &AppState, task_id: &str) -> Result<(Value, u16), (Value, u16)> {
    let read_at = now_iso();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-read").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let rows = client
        .query(
            "
            UPDATE unidesk_code_queue_tasks
            SET read_at = $2::text::timestamptz,
                task_json = jsonb_set(task_json, '{readAt}', to_jsonb($2::text), true)
            WHERE id = $1
              AND status IN ('succeeded', 'failed', 'canceled')
              AND read_at IS NULL
            RETURNING id, status
            ",
            &[&task_id, &read_at],
        )
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    if rows.is_empty() {
        let Some(task) = load_task(state, task_id, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))? else {
            return Ok((json!({ "ok": false, "error": "task not found" }), 404));
        };
        if !terminal_status(&task.status) {
            return Ok((json!({ "ok": false, "error": format!("task is not terminal: {}", task.status) }), 409));
        }
        return Ok((json!({ "ok": true, "task": task_list_response(state, &task, true), "queue": summary }), 200));
    }
    Ok((json!({ "ok": true, "task": { "id": task_id, "readAt": read_at, "terminalUnread": false }, "queue": summary }), 200))
}

fn mark_all_read(state: &AppState, url: &RequestUrl) -> Result<(Value, u16), (Value, u16)> {
    let read_at = now_iso();
    let queue_id = query_param(url, "queueId").filter(|value| !value.is_empty()).map(|value| safe_queue_id(&value));
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-read-all").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let rows = client
        .query(
            "
            UPDATE unidesk_code_queue_tasks
            SET read_at = $2::text::timestamptz,
                task_json = jsonb_set(task_json, '{readAt}', to_jsonb($2::text), true)
            WHERE ($1::text IS NULL OR queue_id = $1)
              AND status IN ('succeeded', 'failed', 'canceled')
              AND read_at IS NULL
            RETURNING id
            ",
            &[&queue_id, &read_at],
        )
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((json!({ "ok": true, "count": rows.len(), "readAt": read_at, "queue": summary }), 200))
}

fn manual_retry_status_sql_condition() -> &'static str {
    "started_at IS NULL AND current_attempt = 0 AND codex_thread_id IS NULL AND active_turn_id IS NULL AND attempt_count = 0"
}

fn manual_retry_status_sql_value() -> String {
    format!(
        "CASE WHEN {} THEN 'queued'::text ELSE 'retry_wait'::text END",
        manual_retry_status_sql_condition()
    )
}

fn manual_retry_task_json_sql_expression() -> String {
    let next_status = manual_retry_status_sql_value();
    format!(
        "
        jsonb_set(
          jsonb_set(
            jsonb_set(
              jsonb_set(
                jsonb_set(
                  jsonb_set(
                    jsonb_set(
                      jsonb_set(
                        jsonb_set(task_json, '{{status}}', to_jsonb({next_status}), true),
                        '{{finishedAt}}', 'null'::jsonb, true
                      ),
                      '{{readAt}}', 'null'::jsonb, true
                    ),
                    '{{cancelRequested}}', 'false'::jsonb, true
                  ),
                  '{{lastError}}', 'null'::jsonb, true
                ),
                '{{maxAttempts}}', to_jsonb(GREATEST(max_attempts, current_attempt + 1, attempt_count + 1)), true
              ),
              '{{updatedAt}}', to_jsonb($2::text), true
            ),
            '{{queueEnteredAt}}', to_jsonb($2::text), true
          ),
          '{{nextMode}}', to_jsonb('retry'::text), true
        )
        "
    )
}

fn move_task(state: &AppState, task_id: &str, request: &mut Request) -> Result<(Value, u16), (Value, u16)> {
    let body = read_json_body(request)?;
    let queue_id = validate_queue_id(body.get("queueId").or_else(|| body.get("id")).and_then(Value::as_str).unwrap_or(DEFAULT_QUEUE_ID))
        .map_err(|error| (json!({ "ok": false, "error": error }), 400))?;
    let moved_at = now_iso();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-move").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let mut transaction = client.transaction().map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    transaction
        .execute(
            "
            INSERT INTO unidesk_code_queue_queues (id, name, created_at, updated_at)
            VALUES ($1, $1, $2::text::timestamptz, $2::text::timestamptz)
            ON CONFLICT (id) DO UPDATE SET updated_at = GREATEST(unidesk_code_queue_queues.updated_at, EXCLUDED.updated_at)
            ",
            &[&queue_id, &moved_at],
        )
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    let rows = transaction
        .query(
            "
            UPDATE unidesk_code_queue_tasks
            SET queue_id = $2,
                updated_at = $3::text::timestamptz,
                task_json = jsonb_set(jsonb_set(jsonb_set(task_json, '{queueId}', to_jsonb($2::text), true), '{queueEnteredAt}', to_jsonb($3::text), true), '{updatedAt}', to_jsonb($3::text), true)
            WHERE id = $1
              AND status IN ('queued', 'retry_wait')
              AND started_at IS NULL
              AND current_attempt = 0
              AND codex_thread_id IS NULL
              AND active_turn_id IS NULL
            RETURNING id
            ",
            &[&task_id, &queue_id, &moved_at],
        )
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    transaction.commit().map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    if rows.is_empty() {
        let Some(task) = load_task(state, task_id, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))? else {
            return Ok((json!({ "ok": false, "error": "task not found" }), 404));
        };
        return Ok((json!({ "ok": false, "error": format!("cannot move task {task_id}: task is not unclaimed queued/retry_wait"), "task": task_list_response(state, &task, true) }), 409));
    }
    let task = load_task(state, task_id, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))?.expect("moved task");
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((json!({ "ok": true, "task": task_list_response(state, &task, false), "queue": summary }), 202))
}

fn retry_task(state: &AppState, task_id: &str, request: &mut Request) -> Result<(Value, u16), (Value, u16)> {
    let body = read_json_body(request)?;
    let prompt = body
        .get("prompt")
        .or_else(|| body.get("continuePrompt"))
        .and_then(Value::as_str)
        .filter(|value| !value.trim().is_empty())
        .unwrap_or("Manual retry requested from master code-queue-mgr. Continue the original task and produce a visible final response.")
        .to_string();
    let queued_at = now_iso();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-retry").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let retry_status = manual_retry_status_sql_value();
    let task_json_update = manual_retry_task_json_sql_expression();
    let sql = format!(
        "
            UPDATE unidesk_code_queue_tasks
            SET status = {retry_status},
                finished_at = NULL,
                read_at = NULL,
                last_error = NULL,
                max_attempts = GREATEST(max_attempts, current_attempt + 1, attempt_count + 1),
                updated_at = $2::text::timestamptz,
                task_json = jsonb_set(
                  {task_json_update},
                  '{{nextPrompt}}', to_jsonb($3::text), true
                )
            WHERE id = $1
              AND (status IN ('succeeded', 'failed', 'canceled') OR (status IN ('queued', 'retry_wait') AND active_turn_id IS NULL AND (started_at IS NOT NULL OR current_attempt > 0 OR codex_thread_id IS NOT NULL)))
            RETURNING id
            "
    );
    let rows = client
        .query(sql.as_str(), &[&task_id, &queued_at, &prompt])
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    if rows.is_empty() {
        let Some(task) = load_task(state, task_id, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))? else {
            return Ok((json!({ "ok": false, "error": "task not found" }), 404));
        };
        return Ok((json!({ "ok": false, "error": format!("task cannot be retried from status={}", task.status), "task": task_list_response(state, &task, true) }), 409));
    }
    let task = load_task(state, task_id, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))?.expect("retried task");
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((json!({ "ok": true, "task": task_list_response(state, &task, false), "queue": summary }), 202))
}

fn edit_task(state: &AppState, task_id: &str, request: &mut Request) -> Result<(Value, u16), (Value, u16)> {
    let body = read_json_body(request)?;
    let raw_prompt = body.get("prompt").and_then(Value::as_str).ok_or_else(|| (json!({ "ok": false, "error": "prompt is required" }), 400))?;
    if raw_prompt.trim().is_empty() {
        return Ok((json!({ "ok": false, "error": "prompt is required" }), 400));
    }
    let prompt = prompt_with_environment_hint(raw_prompt);
    let base_prompt = body.get("basePrompt").and_then(Value::as_str).filter(|value| !value.is_empty()).map(ToString::to_string).unwrap_or_else(|| user_prompt_for_display(raw_prompt));
    let reference_task_ids = json!(collect_reference_ids(body.get("referenceTaskIds").or_else(|| body.get("referenceTaskId"))));
    let edited_at = now_iso();
    let mut client = db_client(state, "unidesk-code-queue-mgr-rust-edit").map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    let rows = client
        .query(
            "
            UPDATE unidesk_code_queue_tasks
            SET prompt = $2,
                base_prompt = $3,
                reference_task_ids = $4,
                updated_at = $5::text::timestamptz,
                task_json = jsonb_set(jsonb_set(jsonb_set(jsonb_set(task_json, '{prompt}', to_jsonb($2::text), true), '{basePrompt}', to_jsonb($3::text), true), '{referenceTaskIds}', $4, true), '{updatedAt}', to_jsonb($5::text), true)
            WHERE id = $1
              AND status = 'queued'
              AND started_at IS NULL
              AND current_attempt = 0
              AND codex_thread_id IS NULL
              AND active_turn_id IS NULL
              AND COALESCE(attempt_count, 0) = 0
            RETURNING id
            ",
            &[&task_id, &prompt, &base_prompt, &reference_task_ids, &edited_at],
        )
        .map_err(|error| (json!({ "ok": false, "error": error.to_string() }), 500))?;
    if rows.is_empty() {
        let Some(task) = load_task(state, task_id, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))? else {
            return Ok((json!({ "ok": false, "error": "task not found" }), 404));
        };
        return Ok((json!({ "ok": false, "error": format!("task prompt can only be edited before first run while status=queued; current status={}", task.status), "task": task_list_response(state, &task, true) }), 409));
    }
    let task = load_task(state, task_id, false).map_err(|error| (json!({ "ok": false, "error": error }), 500))?.expect("edited task");
    let summary = queue_summary(state).map_err(|error| (json!({ "ok": false, "error": error }), 500))?;
    Ok((json!({ "ok": true, "changed": true, "editable": true, "task": task_list_response(state, &task, false), "queue": summary }), 200))
}

fn health(state: &AppState) -> (Value, u16) {
    let mut task_count: Option<i64> = None;
    let ready;
    let mut last_error = schema_last_error(state);
    match db_client(state, "unidesk-code-queue-mgr-rust-health").and_then(|mut client| {
        client
            .query_one("SELECT COUNT(*)::bigint AS count FROM unidesk_code_queue_tasks", &[])
            .map(|row| row.get::<_, i64>("count"))
            .map_err(|error| error.to_string())
    }) {
        Ok(count) => {
            task_count = Some(count);
            ready = true;
            set_schema_ready(state, true, None);
        }
        Err(error) => {
            ready = false;
            last_error = Some(json!({ "message": error.clone() }));
            set_schema_ready(state, false, last_error.clone());
        }
    }
    let body = json!({
        "ok": ready,
        "service": "code-queue-mgr",
        "role": "master-control-plane",
        "runtime": { "language": "rust", "http": "tiny_http", "db": "postgres-sync-per-request" },
        "deploy": {
            "serviceId": state.config.deploy_service_id,
            "repo": state.config.deploy_repo,
            "commit": state.config.deploy_commit,
            "requestedCommit": state.config.deploy_requested_commit
        },
        "startedAt": state.started_at,
        "schemaReady": ready,
        "schemaLastError": last_error,
        "taskCount": task_count,
        "queue": if ready { queue_summary(state).unwrap_or(Value::Null) } else { Value::Null },
        "resourceBudget": {
            "targetMemoryMb": 100,
            "mgrPoolMax": state.config.mgr_pool_max,
            "tracePoolMax": state.config.trace_pool_max,
            "noRunnerDependencies": true,
            "noPlaywright": true,
            "noCodexRuntime": true,
            "noDockerSocket": true,
            "rustRewrite": true,
            "readPath": "column-first"
        },
        "endpoints": {
            "control": ["/api/queues", "/api/tasks", "/api/tasks/:id/(move|retry|read|edit)", "/api/workdirs", "/api/queue-claim-move/self-test"],
            "traceRead": ["/api/tasks/overview", "/api/tasks/:id/summary", "/api/tasks/:id/trace-summary", "/api/tasks/:id/trace-steps", "/api/tasks/:id/output"]
        }
    });
    (body, if ready { 200 } else { 503 })
}

fn route_active_control(path: &str, method: &Method) -> Option<(Value, u16)> {
    if path.ends_with("/steer") || path.ends_with("/interrupt") {
        return Some((json!({ "ok": false, "error": "active run control remains on D601 scheduler", "method": method.as_str(), "schedulerPath": path }), 409));
    }
    if method == &Method::Delete && path.starts_with("/api/tasks/") {
        return Some((json!({ "ok": false, "error": "active run interrupt remains on D601 scheduler", "method": method.as_str(), "schedulerPath": path }), 409));
    }
    None
}

fn task_id_and_suffix(path: &str) -> Option<(String, String)> {
    let rest = path.strip_prefix("/api/tasks/")?;
    let mut parts = rest.splitn(2, '/');
    let id = parts.next().unwrap_or_default();
    if id.is_empty() {
        return None;
    }
    let suffix = parts.next().unwrap_or_default().to_string();
    Some((percent_decode(id), suffix))
}

fn queue_id_and_suffix(path: &str) -> Option<(String, String)> {
    let rest = path.strip_prefix("/api/queues/")?;
    let mut parts = rest.splitn(2, '/');
    let id = parts.next().unwrap_or_default();
    if id.is_empty() {
        return None;
    }
    let suffix = parts.next().unwrap_or_default().to_string();
    Some((percent_decode(id), suffix))
}

fn percent_decode(value: &str) -> String {
    let bytes = value.as_bytes();
    let mut output = Vec::with_capacity(bytes.len());
    let mut index = 0;
    while index < bytes.len() {
        if bytes[index] == b'+' {
            output.push(b' ');
            index += 1;
            continue;
        }
        if bytes[index] == b'%' && index + 2 < bytes.len() {
            if let (Some(high), Some(low)) = (hex_value(bytes[index + 1]), hex_value(bytes[index + 2])) {
                output.push((high << 4) | low);
                index += 3;
                continue;
            }
        }
        output.push(bytes[index]);
        index += 1;
    }
    String::from_utf8_lossy(&output).into_owned()
}

fn hex_value(value: u8) -> Option<u8> {
    match value {
        b'0'..=b'9' => Some(value - b'0'),
        b'a'..=b'f' => Some(value - b'a' + 10),
        b'A'..=b'F' => Some(value - b'A' + 10),
        _ => None,
    }
}

fn handle_request(state: &AppState, request: &mut Request) -> (Value, u16) {
    let method = request.method().clone();
    if method == Method::Options {
        return (json!({}), 204);
    }
    let url = parse_url(request.url());
    let path = url.path.as_str();
    if path == "/" || path == "/health" || path == "/live" {
        return health(state);
    }
    if path == "/logs" && method == Method::Get {
        let logs: Vec<Value> = state.logs.lock().map(|items| items.iter().cloned().collect()).unwrap_or_default();
        return (json!({ "ok": true, "logs": logs }), 200);
    }
    if !schema_ready(state) && path.starts_with("/api/") {
        return (json!({ "ok": false, "error": "code-queue-mgr database schema is not ready", "schemaLastError": schema_last_error(state) }), 503);
    }
    if path == "/api/queue-claim-move/self-test" && (method == Method::Get || method == Method::Post) {
        return (json!({ "ok": true, "runtime": "rust", "check": "route-present", "claimMoveSafety": "conditional update requires unclaimed queued/retry_wait task" }), 200);
    }
    if path == "/api/workdirs" && method == Method::Get {
        return list_workdirs(state, &url).unwrap_or_else(|response| response);
    }
    if path == "/api/workdirs" && method == Method::Post {
        return create_workdir(state, request).unwrap_or_else(|response| response);
    }
    if method == Method::Delete {
        if let Some(rest) = path.strip_prefix("/api/workdirs/") {
            let mut parts = rest.splitn(3, '/');
            let provider_id = parts.next().unwrap_or_default();
            let execution_mode = parts.next().unwrap_or_default();
            let path_value = parts.next().unwrap_or_default();
            if !provider_id.is_empty() && !execution_mode.is_empty() && !path_value.is_empty() {
                return delete_workdir(
                    state,
                    &percent_decode(provider_id),
                    &percent_decode(execution_mode),
                    &percent_decode(path_value),
                )
                .unwrap_or_else(|response| response);
            }
        }
    }
    if let Some(response) = route_active_control(path, &method) {
        return response;
    }
    match (method.clone(), path) {
        (Method::Get, "/api/queues") => match queue_summary(state) {
            Ok(summary) => {
                let queues = summary.get("queues").cloned().unwrap_or_else(|| json!([]));
                (json!({ "ok": true, "queues": queues, "queue": summary }), 200)
            }
            Err(error) => (json!({ "ok": false, "error": error }), 500),
        },
        (Method::Post, "/api/queues") => return create_queue(state, request).unwrap_or_else(|response| response),
        (Method::Post, "/api/queues/merge") => (json!({ "ok": false, "error": "queue merge requires /api/queues/:target/merge on rust mgr" }), 400),
        (Method::Get, "/api/tasks/overview") => return tasks_overview(state, &url).unwrap_or_else(|response| response),
        (Method::Get, "/api/tasks/stats") => match (
            task_statistics_summary(state, codex_stats_queue_id_from_url(&url), codex_stats_days_from_url(&url)),
            queue_summary(state),
        ) {
            (Ok(statistics), Ok(summary)) => (json!({ "ok": true, "statistics": statistics, "queue": summary }), 200),
            (Err(error), _) | (_, Err(error)) => (json!({ "ok": false, "error": error }), 500),
        },
        (Method::Get, "/api/tasks") => {
            match load_tasks_for_list(state, &url, false).and_then(|(tasks, total, limit, offset)| {
                queue_summary(state).map(|summary| (tasks, total, limit, offset, summary))
            }) {
                Ok((tasks, total, limit, offset, summary)) => (
                    json!({
                        "ok": true,
                        "tasks": tasks.iter().map(|task| task_list_response(state, task, query_param(&url, "lite").as_deref() == Some("1"))).collect::<Vec<_>>(),
                        "queue": summary,
                        "pagination": { "limit": limit, "offset": offset, "total": total, "returned": tasks.len(), "hasMore": (offset + tasks.len() as i64) < total }
                    }),
                    200,
                ),
                Err(error) => (json!({ "ok": false, "error": error }), 500),
            }
        }
        (Method::Post, "/api/tasks") | (Method::Post, "/api/tasks/batch") => return create_tasks(state, request).unwrap_or_else(|response| response),
        (Method::Post, "/api/tasks/read-all") => return mark_all_read(state, &url).unwrap_or_else(|response| response),
        _ => {
            if let Some((queue_id, suffix)) = queue_id_and_suffix(path) {
                if suffix == "merge" && method == Method::Post {
                    return (json!({ "ok": false, "error": "queue merge is temporarily disabled on rust mgr until D601 scheduler is stable", "targetQueueId": queue_id }), 409);
                }
                if suffix.is_empty() && matches!(method, Method::Patch | Method::Put | Method::Post) {
                    return update_queue(state, &queue_id, request).unwrap_or_else(|response| response);
                }
            }
            if let Some((task_id, suffix)) = task_id_and_suffix(path) {
                if suffix == "output" && method == Method::Get {
                    return match load_task(state, &task_id, true) {
                        Ok(Some(task)) => (output_page(&task, &url), 200),
                        Ok(None) => (json!({ "ok": false, "error": "task not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
                if suffix == "transcript" && method == Method::Get {
                    return match load_task(state, &task_id, true) {
                        Ok(Some(task)) => (transcript_page(&task, &url), 200),
                        Ok(None) => (json!({ "ok": false, "error": "task not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
                if suffix == "trace-summary" && method == Method::Get {
                    return match load_task(state, &task_id, true) {
                        Ok(Some(task)) => (json!({ "ok": true, "summary": trace_summary(&task) }), 200),
                        Ok(None) => (json!({ "ok": false, "error": "task not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
                if suffix == "trace-steps" && method == Method::Get {
                    return match load_task(state, &task_id, true) {
                        Ok(Some(task)) => (trace_steps(&task, &url), 200),
                        Ok(None) => (json!({ "ok": false, "error": "task not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
                if suffix == "trace-step" && method == Method::Get {
                    return match load_task(state, &task_id, true) {
                        Ok(Some(task)) => {
                            let body = trace_step_detail(&task, &url);
                            let status = if body.get("ok").and_then(Value::as_bool) == Some(true) { 200 } else { 404 };
                            (body, status)
                        }
                        Ok(None) => (json!({ "ok": false, "error": "trace step not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
                if suffix == "summary" && method == Method::Get {
                    return match load_task(state, &task_id, true) {
                        Ok(Some(task)) => (json!({ "ok": true, "summary": task_summary(&task) }), 200),
                        Ok(None) => (json!({ "ok": false, "error": "task not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
                if suffix == "prompt" && method == Method::Get {
                    return match load_task(state, &task_id, false) {
                        Ok(Some(task)) => {
                            let part = query_param(&url, "part").unwrap_or_else(|| "initial".to_string());
                            let text = if part == "base" { task.base_prompt } else { task.prompt };
                            (json!({ "ok": true, "taskId": task.id, "part": part, "text": text, "chars": text.chars().count(), "lines": text.lines().count() }), 200)
                        }
                        Ok(None) => (json!({ "ok": false, "error": "task not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
                if suffix == "prompt" && method == Method::Patch {
                    return edit_task(state, &task_id, request).unwrap_or_else(|response| response);
                }
                if suffix == "retry" && method == Method::Post {
                    return retry_task(state, &task_id, request).unwrap_or_else(|response| response);
                }
                if suffix == "move" && method == Method::Post {
                    return move_task(state, &task_id, request).unwrap_or_else(|response| response);
                }
                if suffix == "read" && method == Method::Post {
                    return mark_task_read(state, &task_id).unwrap_or_else(|response| response);
                }
                if suffix == "edit" && (method == Method::Post || method == Method::Patch) {
                    return edit_task(state, &task_id, request).unwrap_or_else(|response| response);
                }
                if suffix.is_empty() && method == Method::Get {
                    return match load_task(state, &task_id, true) {
                        Ok(Some(task)) => {
                            if query_param(&url, "meta").as_deref() == Some("1") {
                                (json!({ "ok": true, "task": task_meta_response(state, &task) }), 200)
                            } else {
                                let mut full = task_meta_response(state, &task);
                                if let Some(map) = full.as_object_mut() {
                                    map.insert("output".to_string(), json!(output_array(&task)));
                                    map.insert("events".to_string(), task.task_json.as_ref().and_then(|value| value.get("events")).cloned().unwrap_or_else(|| json!([])));
                                }
                                (json!({ "ok": true, "task": full }), 200)
                            }
                        }
                        Ok(None) => (json!({ "ok": false, "error": "task not found" }), 404),
                        Err(error) => (json!({ "ok": false, "error": error }), 500),
                    };
                }
            }
            (json!({ "ok": false, "error": "not found", "path": path }), 404)
        }
    }
}

fn main() {
    let config = match config_from_env() {
        Ok(value) => value,
        Err(error) => {
            eprintln!("{}", json!({ "ok": false, "error": error }));
            std::process::exit(1);
        }
    };
    if env::args().any(|arg| arg == "--healthcheck") {
        std::process::exit(if run_healthcheck(config.port) { 0 } else { 1 });
    }
    if env::args().any(|arg| arg == "--print-health") {
        std::process::exit(if print_health(config.port) { 0 } else { 1 });
    }
    let state = AppState {
        config,
        started_at: now_iso(),
        logs: Arc::new(Mutex::new(VecDeque::new())),
        schema_ready: Arc::new(Mutex::new(false)),
        schema_last_error: Arc::new(Mutex::new(None)),
        last_database_error: Arc::new(Mutex::new(None)),
    };
    ensure_schema_with_retry(state.clone());
    let address = format!("{}:{}", state.config.host, state.config.port);
    let server = Server::http(&address).unwrap_or_else(|error| {
        eprintln!("{}", json!({ "ok": false, "error": format!("failed to bind {address}: {error}") }));
        std::process::exit(1);
    });
    log_event(&state, "info", "service_listening", json!({ "port": state.config.port, "role": "master-control-plane", "runtime": "rust", "mgrPoolMax": state.config.mgr_pool_max, "tracePoolMax": state.config.trace_pool_max }));
    for mut request in server.incoming_requests() {
        let path = request.url().to_string();
        let method = request.method().as_str().to_string();
        let (body, status) = match std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| handle_request(&state, &mut request))) {
            Ok(response) => response,
            Err(_) => (json!({ "ok": false, "error": "request panicked" }), 500),
        };
        if status >= 500 {
            log_event(&state, "error", "request_failed", json!({ "path": path, "method": method, "status": status, "body": body.clone() }));
        }
        let _ = request.respond(json_response(body, status));
    }
}

fn run_healthcheck(port: u16) -> bool {
    let Ok(mut stream) = TcpStream::connect(("127.0.0.1", port)) else {
        return false;
    };
    let _ = stream.set_read_timeout(Some(std::time::Duration::from_secs(3)));
    let _ = stream.set_write_timeout(Some(std::time::Duration::from_secs(3)));
    if stream
        .write_all(b"GET /health HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n")
        .is_err()
    {
        return false;
    }
    let mut body = String::new();
    stream.read_to_string(&mut body).is_ok() && body.contains("\"ok\": true")
}

fn print_health(port: u16) -> bool {
    let Ok(mut stream) = TcpStream::connect(("127.0.0.1", port)) else {
        return false;
    };
    let _ = stream.set_read_timeout(Some(std::time::Duration::from_secs(3)));
    let _ = stream.set_write_timeout(Some(std::time::Duration::from_secs(3)));
    if stream
        .write_all(b"GET /health HTTP/1.1\r\nHost: 127.0.0.1\r\nConnection: close\r\n\r\n")
        .is_err()
    {
        return false;
    }
    let mut response = String::new();
    if stream.read_to_string(&mut response).is_err() {
        return false;
    }
    if let Some((_, body)) = response.split_once("\r\n\r\n") {
        println!("{}", body.trim());
    } else {
        println!("{}", response.trim());
    }
    response.contains("\"ok\": true")
}

#[cfg(test)]
mod tests {
    use super::*;

    fn test_state() -> AppState {
        AppState {
            config: Config {
                host: "127.0.0.1".to_string(),
                port: 4278,
                database_url: "postgres://unused".to_string(),
                log_file: "/tmp/unidesk-code-queue-mgr-test.jsonl".to_string(),
                deploy_service_id: "code-queue-mgr".to_string(),
                deploy_repo: "".to_string(),
                deploy_commit: "".to_string(),
                deploy_requested_commit: "".to_string(),
                mgr_pool_max: 1,
                trace_pool_max: 1,
                default_provider_id: "D601".to_string(),
                default_workdir: "/workspace".to_string(),
                remote_default_workdir: "/home/ubuntu".to_string(),
                default_model: "gpt-5.5".to_string(),
                code_models: vec!["gpt-5.5".to_string()],
                default_max_attempts: 1,
                default_reasoning_effort: None,
                model_reasoning_efforts: json!({}),
            },
            started_at: now_iso(),
            logs: Arc::new(Mutex::new(VecDeque::new())),
            schema_ready: Arc::new(Mutex::new(false)),
            schema_last_error: Arc::new(Mutex::new(None)),
            last_database_error: Arc::new(Mutex::new(None)),
        }
    }

    fn long_prompt(marker: &str) -> String {
        let filler = (0..76)
            .map(|index| format!("long-prompt-line-{index:02} {}", "abcdefghijklmnopqrstuvwxyz0123456789".repeat(2)))
            .collect::<Vec<_>>()
            .join("\n");
        [
            "Code Queue long prompt observation contract".to_string(),
            "".to_string(),
            filler,
            "".to_string(),
            "验收标准：".to_string(),
            format!("所有原始 prompt 观察层必须保留这个唯一 tail marker: {marker}"),
        ]
        .join("\n")
    }

    fn test_task(prompt: String) -> TaskMeta {
        let at = now_iso();
        TaskMeta {
            id: "codex_1779000000000_longprompt".to_string(),
            queue_id: "e2e-long-prompt".to_string(),
            status: "queued".to_string(),
            provider_id: "D601".to_string(),
            execution_mode: "default".to_string(),
            model: "gpt-5.5".to_string(),
            cwd: "/home/ubuntu".to_string(),
            prompt: prompt.clone(),
            base_prompt: prompt,
            reference_task_ids: json!([]),
            reference_injection: None,
            reasoning_effort: None,
            max_attempts: 1,
            current_attempt: 0,
            current_mode: None,
            codex_thread_id: None,
            active_turn_id: None,
            created_at: at.clone(),
            updated_at: at,
            started_at: None,
            finished_at: None,
            read_at: None,
            last_error: None,
            last_judge: None,
            output_count: 1,
            event_count: 0,
            attempt_count: 0,
            last_output_seq: 1,
            task_json: Some(json!({
                "queueEnteredAt": now_iso(),
                "finalResponse": "",
                "stepCount": 0,
                "llmStepCount": 0,
                "judgeFailCount": 0,
                "cancelRequested": false,
                "attempts": [],
                "output": [],
                "events": [],
                "promptHistory": []
            })),
        }
    }

    fn field_text<'a>(value: &'a Value, key: &str) -> &'a str {
        value.get(key).and_then(Value::as_str).unwrap_or("")
    }

    fn json_bool(task: &TaskMeta, key: &str) -> Option<bool> {
        task.task_json.as_ref().and_then(|value| value.get(key)).and_then(Value::as_bool)
    }

    fn apply_manual_retry_contract_for_test(task: &TaskMeta, queued_at: &str, prompt: &str) -> TaskMeta {
        let mut next = task.clone();
        let claimed = next.started_at.is_some()
            || next.current_attempt > 0
            || next.codex_thread_id.is_some()
            || next.active_turn_id.is_some()
            || next.attempt_count > 0;
        next.status = if claimed { "retry_wait" } else { "queued" }.to_string();
        next.finished_at = None;
        next.read_at = None;
        next.last_error = None;
        next.max_attempts = next.max_attempts.max(next.current_attempt + 1).max(next.attempt_count + 1);
        next.updated_at = queued_at.to_string();
        let mut task_json = next.task_json.take().unwrap_or_else(|| json!({}));
        let json_object = task_json.as_object_mut().expect("test task json object");
        json_object.insert("status".to_string(), json!(next.status));
        json_object.insert("finishedAt".to_string(), Value::Null);
        json_object.insert("readAt".to_string(), Value::Null);
        json_object.insert("cancelRequested".to_string(), Value::Bool(false));
        json_object.insert("lastError".to_string(), Value::Null);
        json_object.insert("maxAttempts".to_string(), json!(next.max_attempts));
        json_object.insert("updatedAt".to_string(), json!(queued_at));
        json_object.insert("queueEnteredAt".to_string(), json!(queued_at));
        json_object.insert("nextMode".to_string(), json!("retry"));
        json_object.insert("nextPrompt".to_string(), json!(prompt));
        next.task_json = Some(task_json);
        next
    }

    #[test]
    fn prompt_observation_preserves_raw_fields_and_explicit_previews() {
        let state = test_state();
        let marker = "RUST_PROMPT_OBSERVATION_TAIL_MARKER";
        let prompt = long_prompt(marker);
        assert!(prompt.chars().count() > 2500);
        let task = test_task(prompt);
        let create = task_list_response(&state, &task, false);
        let overview = task_list_response(&state, &task, true);
        let meta = task_meta_response(&state, &task);
        let raw_fields = [
            field_text(&create, "prompt"),
            field_text(&create, "basePrompt"),
            field_text(&create, "displayPrompt"),
            field_text(&overview, "prompt"),
            field_text(&overview, "basePrompt"),
            field_text(&overview, "displayPrompt"),
            field_text(&meta, "prompt"),
            field_text(&meta, "basePrompt"),
            field_text(&meta, "displayPrompt"),
            field_text(&meta, "initialPrompt"),
        ];
        assert!(raw_fields.iter().all(|value| value.contains(marker)), "{raw_fields:?}");
        assert!(raw_fields.iter().all(|value| !value.contains("...<truncated>")), "{raw_fields:?}");

        let preview = overview.get("promptPreview").and_then(Value::as_object).expect("promptPreview metadata");
        assert_eq!(preview.get("truncated").and_then(Value::as_bool), Some(true));
        assert_eq!(preview.get("chars").and_then(Value::as_u64), Some(field_text(&overview, "prompt").chars().count() as u64));
        assert!(preview.get("text").and_then(Value::as_str).unwrap_or("").contains("...<truncated>"));
        assert!(!preview.get("text").and_then(Value::as_str).unwrap_or("").contains(marker));
    }

    #[test]
    fn default_workdir_contract_includes_workspace() {
        let state = test_state();
        let record = default_workdir_record(&state, "2026-01-01T00:00:00.000Z").expect("default workdir");
        assert_eq!(record.get("providerId").and_then(Value::as_str), Some("D601"));
        assert_eq!(record.get("executionMode").and_then(Value::as_str), Some("default"));
        assert_eq!(record.get("path").and_then(Value::as_str), Some("/workspace"));
    }

    #[test]
    fn manual_retry_sql_clears_cancel_requested_contract() {
        let sql = manual_retry_task_json_sql_expression();
        assert!(sql.contains("'{cancelRequested}', 'false'::jsonb"), "{sql}");
        assert!(sql.contains("'{maxAttempts}', to_jsonb(GREATEST(max_attempts, current_attempt + 1, attempt_count + 1))"), "{sql}");
        assert!(sql.contains("'{queueEnteredAt}', to_jsonb($2::text)"), "{sql}");
        assert!(sql.contains("'{nextMode}', to_jsonb('retry'::text)"), "{sql}");
    }

    #[test]
    fn stats_summary_contract_exposes_daily_buckets_and_totals() {
        let stats = codex_stats_summary_from_rows(
            2,
            "2026-05-20T00:00:00.000Z",
            &[
                DailyTaskStatsRow {
                    date: "2026-05-19".to_string(),
                    executed_tasks: 2,
                    completed_tasks: 1,
                    retry_attempts: 1,
                    succeeded_tasks: 1,
                    failed_tasks: 0,
                    canceled_tasks: 0,
                    total_duration_ms: 120_000,
                    duration_samples: 1,
                },
                DailyTaskStatsRow {
                    date: "2026-05-20".to_string(),
                    executed_tasks: 3,
                    completed_tasks: 2,
                    retry_attempts: 2,
                    succeeded_tasks: 1,
                    failed_tasks: 1,
                    canceled_tasks: 0,
                    total_duration_ms: 480_000,
                    duration_samples: 2,
                },
            ],
        );

        assert_eq!(stats.get("timezone").and_then(Value::as_str), Some("Asia/Shanghai"));
        assert_eq!(stats.pointer("/range/startDate").and_then(Value::as_str), Some("2026-05-19"));
        assert_eq!(stats.pointer("/range/endDate").and_then(Value::as_str), Some("2026-05-20"));
        assert_eq!(stats.pointer("/totals/executedTasks").and_then(Value::as_i64), Some(5));
        assert_eq!(stats.pointer("/totals/completedTasks").and_then(Value::as_i64), Some(3));
        assert_eq!(stats.pointer("/totals/retryAttempts").and_then(Value::as_i64), Some(3));
        assert_eq!(stats.pointer("/totals/failedTasks").and_then(Value::as_i64), Some(1));
        assert_eq!(stats.pointer("/totals/avgDurationMs").and_then(Value::as_i64), Some(200_000));
        let daily = stats.get("daily").and_then(Value::as_array).expect("daily buckets");
        assert_eq!(daily.len(), 2);
        assert_eq!(daily[1].get("avgDurationMs").and_then(Value::as_i64), Some(240_000));
    }

    #[test]
    fn manual_retry_canceled_task_becomes_scheduler_runnable() {
        let state = test_state();
        let canceled_at = "2026-05-19T10:00:00.000Z".to_string();
        let mut task = test_task("interrupted task".to_string());
        task.status = "canceled".to_string();
        task.started_at = Some(canceled_at.clone());
        task.finished_at = Some(canceled_at.clone());
        task.read_at = Some(canceled_at.clone());
        task.current_attempt = 1;
        task.current_mode = Some("initial".to_string());
        task.max_attempts = 1;
        task.last_error = Some("Task canceled by request.".to_string());
        task.attempt_count = 1;
        task.task_json = Some(json!({
            "status": "canceled",
            "queueEnteredAt": "2026-05-19T09:59:00.000Z",
            "finishedAt": canceled_at,
            "readAt": canceled_at,
            "updatedAt": canceled_at,
            "lastError": "Task canceled by request.",
            "finalResponse": "",
            "stepCount": 0,
            "llmStepCount": 0,
            "judgeFailCount": 0,
            "maxAttempts": 1,
            "cancelRequested": true,
            "nextPrompt": Value::Null,
            "nextMode": Value::Null,
            "attempts": [{ "index": 1, "mode": "initial" }],
            "output": [],
            "events": [],
            "promptHistory": []
        }));
        assert_eq!(json_bool(&task, "cancelRequested"), Some(true));

        let retry_prompt = "Manual retry requested from master code-queue-mgr.";
        let retried = apply_manual_retry_contract_for_test(&task, "2026-05-19T10:01:00.000Z", retry_prompt);
        assert_eq!(retried.status, "retry_wait");
        assert_eq!(retried.finished_at, None);
        assert_eq!(retried.read_at, None);
        assert_eq!(retried.last_error, None);
        assert_eq!(retried.max_attempts, 2);
        assert_eq!(json_bool(&retried, "cancelRequested"), Some(false));
        assert_eq!(
            retried.task_json.as_ref().and_then(|value| value.get("nextMode")).and_then(Value::as_str),
            Some("retry")
        );
        assert_eq!(
            retried.task_json.as_ref().and_then(|value| value.get("nextPrompt")).and_then(Value::as_str),
            Some(retry_prompt)
        );

        let scheduler_visible = task_list_response(&state, &retried, false);
        assert_eq!(scheduler_visible.get("status").and_then(Value::as_str), Some("retry_wait"));
        assert_eq!(scheduler_visible.get("cancelRequested").and_then(Value::as_bool), Some(false));
        assert_eq!(
            scheduler_visible.pointer("/queuedReason/code").and_then(Value::as_str),
            Some("mgr-visible")
        );
    }

    #[test]
    fn trace_summary_contract_exposes_retry_window_and_raw_fallback() {
        let mut task = test_task("trace summary retry contract".to_string());
        task.id = "codex_trace_contract_rust".to_string();
        task.status = "running".to_string();
        task.current_attempt = 2;
        task.current_mode = Some("retry".to_string());
        task.max_attempts = 99;
        task.attempt_count = 1;
        task.last_output_seq = 21;
        task.task_json = Some(json!({
            "status": "running",
            "stepCount": Value::Null,
            "llmStepCount": Value::Null,
            "attempts": [
                {
                    "index": 1,
                    "mode": "initial",
                    "startedAt": "2026-05-19T00:00:10.000Z",
                    "finishedAt": "2026-05-19T00:02:00.000Z",
                    "judge": { "decision": "retry", "reason": "try again" }
                }
            ],
            "output": [
                { "seq": 1, "at": "2026-05-19T00:00:00.000Z", "channel": "system", "method": "enqueue", "text": "queued" },
                { "seq": 20, "attempt": 2, "at": "2026-05-19T00:06:00.000Z", "channel": "command", "method": "item/started", "text": "attempt 2 / 99\npnpm test" },
                { "seq": 21, "attempt": 2, "at": "2026-05-19T00:06:20.000Z", "channel": "tool", "method": "item/completed", "text": "src/components/microservices/code-queue-mgr/src-rs/main.rs" }
            ],
            "events": [],
            "promptHistory": []
        }));

        let summary = trace_summary(&task);
        assert_eq!(summary.get("currentAttempt").and_then(Value::as_i64), Some(2));
        assert_eq!(summary.get("statsSource").and_then(Value::as_str), Some("raw-trace-fallback"));
        assert_eq!(summary.get("traceStatsState").and_then(Value::as_str), Some("degraded"));
        assert_eq!(
            summary.get("traceStatsReason").and_then(Value::as_str),
            Some("oa-event-flow-stats-unavailable-raw-trace-present")
        );
        assert_eq!(summary.get("statsUnavailable").and_then(Value::as_bool), Some(true));
        assert_eq!(summary.get("statsSyncing").and_then(Value::as_bool), Some(true));
        assert!(summary.get("stepCount").and_then(Value::as_i64).unwrap_or(0) > 0);

        let attempts = summary.get("attempts").and_then(Value::as_array).expect("attempts array");
        let attempt2 = attempts
            .iter()
            .find(|attempt| attempt.get("index").and_then(Value::as_i64) == Some(2))
            .expect("attempt 2 visible");
        assert_eq!(attempt2.get("stepCount").and_then(Value::as_i64), Some(2));
        assert_eq!(attempt2.get("statsSource").and_then(Value::as_str), Some("raw-trace-fallback"));
        assert_eq!(attempt2.pointer("/execution/traceStatsState").and_then(Value::as_str), Some("degraded"));
    }
}
