cueloop 0.6.0

A Rust CLI for managing AI agent loops with a structured JSON task queue
Documentation
//! Worker prompt loading and rendering tests.
//!
//! Purpose:
//! - Worker prompt loading and rendering tests.
//!
//! Responsibilities: validate worker prompt loading, fallback behavior, and rendering.
//!
//! Scope:
//! - Limited to this file's owning feature boundary.
//!
//! Not handled: phase-specific worker prompts (see phases.rs), task builder, or scan prompts.
//!
//! Usage:
//! - Used through the crate module tree or integration test harness.
//!
//! Invariants/assumptions: embedded defaults are available; temp directories are writable.

use super::*;

#[test]
fn render_worker_prompt_replaces_interactive_instructions() -> Result<()> {
    let template = "Hello\n{{INTERACTIVE_INSTRUCTIONS}}\n";
    let config = default_config();
    let rendered = render_worker_prompt(template, "RQ-0001", ProjectType::Code, &config)?;
    assert!(!rendered.contains("{{INTERACTIVE_INSTRUCTIONS}}"));
    Ok(())
}

#[test]
fn load_worker_prompt_falls_back_to_embedded_default_when_missing() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_prompt(dir.path())?;
    assert!(prompt.contains("# MISSION"));
    Ok(())
}

#[test]
fn default_worker_prompt_includes_followup_ownership_guard() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_prompt(dir.path())?;
    assert!(prompt.contains("QUEUE FOLLOW-UP DISCIPLINE"));
    assert!(prompt.contains("not create follow-ups as a substitute"));
    assert!(prompt.contains(".cueloop/cache/followups/{{TASK_ID}}.json"));
    assert!(prompt.contains("top-level `version` is numeric `1`"));
    assert!(prompt.contains("not `\"followups@v1\"`"));
    assert!(
        prompt.contains("depends_on_keys` may reference only keys defined in the same proposal")
    );
    assert!(prompt.contains("not a report handoff"));
    Ok(())
}

#[test]
fn load_worker_phase1_prompt_falls_back_to_embedded_default_when_missing() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_phase1_prompt(dir.path())?;
    assert!(prompt.contains("# PLANNING MODE"));
    Ok(())
}

#[test]
fn load_worker_phase2_prompt_falls_back_to_embedded_default_when_missing() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_phase2_prompt(dir.path())?;
    assert!(prompt.contains("# IMPLEMENTATION MODE"));
    Ok(())
}

#[test]
fn load_worker_phase2_handoff_prompt_falls_back_to_embedded_default_when_missing() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_phase2_handoff_prompt(dir.path())?;
    assert!(prompt.contains("# IMPLEMENTATION MODE - PHASE 2"));
    assert!(!prompt.contains("so Phase 3 can close them"));
    assert!(prompt.contains("concise handoff summary"));
    assert!(prompt.contains("concrete remediation steps"));
    Ok(())
}

#[test]
fn load_worker_phase3_prompt_falls_back_to_embedded_default_when_missing() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_phase3_prompt(dir.path())?;
    assert!(prompt.contains("# CODE REVIEW MODE"));
    assert!(prompt.contains("agent.ci_gate.enabled=false"));
    assert!(prompt.contains("skip only the configured CI command/requirement"));
    assert!(prompt.contains("continue Phase 3 review/completion work"));
    assert!(prompt.contains("configured CI validation was skipped by configuration"));
    Ok(())
}

#[test]
fn load_worker_single_phase_prompt_falls_back_to_embedded_default_when_missing() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_single_phase_prompt(dir.path())?;
    assert!(prompt.contains("single-pass execution mode"));
    Ok(())
}

#[test]
fn load_worker_prompt_uses_current_override_when_present() -> Result<()> {
    let dir = TempDir::new()?;
    let overrides = dir.path().join(".cueloop/prompts");
    fs::create_dir_all(&overrides)?;
    fs::write(overrides.join("worker.md"), "current override")?;
    let prompt = load_worker_prompt(dir.path())?;
    assert_eq!(prompt, "current override");
    Ok(())
}

#[test]
fn load_worker_prompt_falls_back_to_legacy_override() -> Result<()> {
    let dir = TempDir::new()?;
    let overrides = dir.path().join(".cueloop/prompts");
    fs::create_dir_all(&overrides)?;
    fs::write(overrides.join("worker.md"), "legacy override")?;
    let prompt = load_worker_prompt(dir.path())?;
    assert_eq!(prompt, "legacy override");
    Ok(())
}

#[test]
fn default_worker_prompt_excludes_completion_checklist() -> Result<()> {
    let dir = TempDir::new()?;
    let prompt = load_worker_prompt(dir.path())?;
    assert!(!prompt.contains("IMPLEMENTATION COMPLETION CHECKLIST"));
    assert!(!prompt.contains("END-OF-TURN CHECKLIST"));
    Ok(())
}