yog 0.0.1

yog: a balls-oriented session manager for lernie loops (egui frontend)
Documentation
//! The §7.3 no-response wound: the derivation, its liveness gate, the
//! Altitude-1 predicate, and the sentence that actually reaches the paint
//! output — the bl-8e07 real-substrate finding, driven from its on-disk shape.

use tempfile::tempdir;

use super::render::painted;
use super::{AGENT, write_file};
use crate::git_tree::{AgentState, Framing};
use crate::steps_view::{NO_RESPONSE, StepTab, build, latest_step_no_response};

/// The observed repro: lernie wrote `request.json`, opened `response.json`,
/// and died on a substrate version skew — zero bytes, no `meta.json`.
fn write_repro(ws: &std::path::Path, seq: &str) {
    write_file(ws, seq, "request.json", br#"{"model":"opus"}"#);
    write_file(ws, seq, "response.json", b"");
}

#[test]
fn a_driver_that_wrote_nothing_is_a_wound_not_a_quiet_step() {
    let dir = tempdir().unwrap();
    let ws = dir.path();
    write_repro(ws, "001");

    let view = build(ws, AGENT, AgentState::Stopped);
    let step = &view.steps[0];
    assert!(
        step.no_response,
        "zero-byte response + no meta is the wound"
    );
    // The figures that made the row read quiet are untouched — the wound is a
    // rendered fact beside them, not a different count.
    assert_eq!(step.attempts, 0);
    assert_eq!(step.tokens.total_tokens(), 0);
    assert_eq!(step.framing, Framing::Killed);
    // The §11 Altitude-1 banner keys on the same derivation.
    assert!(latest_step_no_response(ws, AGENT, AgentState::Stopped));
}

#[test]
fn an_absent_response_with_no_meta_is_the_same_wound() {
    let dir = tempdir().unwrap();
    let ws = dir.path();
    // Died before the model call opened the file at all — same fact.
    write_file(ws, "001", "request.json", b"{}");
    assert!(build(ws, AGENT, AgentState::Stopped).steps[0].no_response);
}

#[test]
fn a_step_with_bytes_or_a_settled_meta_is_not_a_wound() {
    let dir = tempdir().unwrap();
    let ws = dir.path();
    // 001 answered; 002 emitted nothing but settled (meta written, however
    // malformed — its bytes say the call returned).
    write_file(
        ws,
        "001",
        "response.json",
        b"{\"type\":\"finish\",\"reason\":\"stop\"}\n{\"type\":\"end\"}\n",
    );
    write_file(ws, "002", "response.json", b"");
    write_file(ws, "002", "meta.json", b"not json at all");
    let view = build(ws, AGENT, AgentState::Stopped);
    assert!(!view.steps[0].no_response);
    assert!(!view.steps[1].no_response);
    assert!(!latest_step_no_response(ws, AGENT, AgentState::Stopped));
    // No steps at all: nothing to banner.
    assert!(!latest_step_no_response(ws, "ghost", AgentState::Stopped));
}

#[test]
fn a_live_drivers_newest_step_is_a_call_in_flight_not_a_wound() {
    let dir = tempdir().unwrap();
    let ws = dir.path();
    write_repro(ws, "001");
    // A driver holds the lock: the newest step is legitimately empty for the
    // moments before the first streamed event (§10 — never a false definite).
    for state in [AgentState::Live, AgentState::InFlight] {
        assert!(!build(ws, AGENT, state).steps[0].no_response);
        assert!(!latest_step_no_response(ws, AGENT, state));
    }
    // Nobody driving: the same bytes are the wound.
    for state in [AgentState::Quiescent, AgentState::Stopped] {
        assert!(build(ws, AGENT, state).steps[0].no_response);
    }
}

#[test]
fn a_live_driver_excuses_only_its_newest_step() {
    let dir = tempdir().unwrap();
    let ws = dir.path();
    write_repro(ws, "001");
    write_repro(ws, "002");
    let view = build(ws, AGENT, AgentState::InFlight);
    assert!(
        view.steps[0].no_response,
        "where the conversation died stays rendered after a resume"
    );
    assert!(!view.steps[1].no_response);
}

#[test]
fn the_wound_reaches_the_paint_output_in_place_of_the_quiet_badge() {
    let dir = tempdir().unwrap();
    let ws = dir.path();
    write_repro(ws, "001");
    let text = painted(
        &build(ws, AGENT, AgentState::Stopped),
        None,
        None,
        StepTab::Meta,
    );
    assert!(text.contains(NO_RESPONSE), "got:\n{text}");
    assert!(text.contains('✗'), "the wound badge, not the ash ■: {text}");
    assert!(!text.contains('■'), "got:\n{text}");
}