yog 0.0.66

yog: the standalone server for litany loops — the world, the balls and the conversations, behind one wire
Documentation
//! The listings (§8.5): what a populating read answered. Each listing carries
//! one row per arm of its row type — the loaded case, the bare case, and every
//! classification token — because a listing whose rows are all the easy case
//! proves only that the easy case survives.

use super::super::super::super::Reply;
use crate::boundary::reply::{ConfigAnswer, PricesView};
use crate::spend::PriceRow;

/// The §11 altitude-0 answers — the enumeration with its §7.2 notes, and one
/// workspace's ball listing — cut off this file at §12's per-file budget
/// (bl-b4b5) on the seam the surface itself draws: those two are what the
/// chrome asks, and everything left here is what a pane asks.
mod chrome;
/// **What a §9 config read answers** (bl-dd88) — one carrier, five members, cut
/// off this file at the budget on the seam that carrier already draws.
mod config;
/// The conversation rows, the widest row type here.
mod convs;
/// The §4.2 trail, whose rows only mean anything together (bl-4d81).
mod trail;
use super::board::board;
use crate::board::Board;
use crate::config_edit::branch::{ConfigBranch, Lineage};
use crate::git_tree::AgentState;
use crate::projects::join::{JoinRow, JoinState};
use crate::search::{Address, Field, Found, Hit};
use convs::conv_rows;

/// The §6 decision queue: a parked row with every signal it can carry, and a
/// quiet one carrying none.
pub(super) fn queue() -> Vec<crate::boundary::answer::queue::QueueRow> {
    use crate::attention::AttentionKind;
    use crate::boundary::answer::queue::QueueRow;
    vec![
        QueueRow {
            workspace: "ws".into(),
            agent: "c-1".into(),
            display: "Cobalt".into(),
            state: AgentState::Stopped,
            uncertain: false,
            signals: vec![
                AttentionKind::Held,
                AttentionKind::Mail,
                AttentionKind::Flagged,
            ],
            preview: "p".into(),
            age_secs: 5,
            pending: 2,
            held: Some(crate::control::hold::Held {
                tool_use_id: "toolu_1".into(),
                tool: "Bash".into(),
                reason: "writes".into(),
            }),
            // The `refused` signal's words (bl-9b88): the corpus pins the
            // sentence beside the class, since a class alone is what the live
            // sighting already had.
            failure: Some("Unauthorized".into()),
            // …and the flag's own words beside them (bl-6f2f): the queue row is
            // the "attention item" VISION §4.9 promises, so the corpus pins the
            // sentence the raiser wrote.
            flag: Some(crate::monitor::Flag {
                at: "2026-01-01T00:00:00Z".into(),
                reason: "please look at this one".into(),
            }),
        },
        QueueRow {
            workspace: "ws".into(),
            agent: "c-2".into(),
            display: "Dun".into(),
            state: AgentState::Live,
            uncertain: true,
            signals: vec![],
            preview: String::new(),
            age_secs: 0,
            pending: 0,
            held: None,
            failure: None,
            flag: None,
        },
    ]
}

/// All three §8.5 address shapes, so the flattened keys are read back under
/// the token that named them rather than by luck of which keys are present.
fn found() -> Found {
    Found {
        needle: "gate".into(),
        hits: vec![
            Hit {
                at: Address::Ball {
                    project: "p".into(),
                    id: "bl-1".into(),
                },
                field: Field::Name,
                offset: 0,
                excerpt: "bl-1".into(),
            },
            Hit {
                at: Address::Workspace { name: "ws".into() },
                field: Field::Summary,
                offset: 3,
                excerpt: "ws".into(),
            },
            Hit {
                at: Address::Conversation {
                    workspace: "ws".into(),
                    agent: "c-1".into(),
                },
                field: Field::Text,
                offset: 12,
                excerpt: "the gate".into(),
            },
        ],
        unreadable: vec!["p: balls unlistable".into()],
    }
}

pub(super) fn listings() -> Vec<Reply> {
    let mut out = chrome::chrome();
    out.extend([
        // The §11 altitude-0 answers, in their own file at the budget.
        Reply::Conversations(conv_rows()),
        Reply::Balls(vec![
            JoinRow {
                project: "p".into(),
                ball_id: "bl-1".into(),
                state: JoinState::Delivered,
                workspace: Some("ws".into()),
                claimant: Some("alba".into()),
                title: Some("t".into()),
            },
            JoinRow {
                project: "p".into(),
                ball_id: "bl-2".into(),
                state: JoinState::ReadyStartable,
                workspace: None,
                claimant: None,
                title: None,
            },
        ]),
        Reply::Board(board()),
        // The unarmed world, whose `fleet` key is absent rather than empty.
        Reply::Board(Board::default()),
        // The §3.5 table, ceiling and ledger (bl-53d1), at both of its
        // shapes: a ceiling act's receipt over a priced world — a `*` row
        // beside a named one, the bound, the floor with unpriced tokens on
        // it, and the count — and a read of an unpriced, unbounded world,
        // where all three keys are absent rather than zero.
        Reply::Prices(PricesView {
            rows: vec![
                PriceRow {
                    provider: "anthropic".into(),
                    model: crate::spend::ANY.into(),
                    rates: crate::spend::Price {
                        input: 3_000_000,
                        output: 15_000_000,
                        cache_read: 300_000,
                        cache_write: 3_750_000,
                    },
                },
                PriceRow {
                    provider: "claude-session-direct".into(),
                    model: "claude-opus-4-1".into(),
                    rates: crate::spend::Price::default(),
                },
            ],
            ceiling: crate::spend::Ceiling::from_json(Some(&serde_json::json!(25))),
            spent: Some(crate::spend::Cost {
                micro_usd: 4_250_000,
                unpriced_tokens: 12,
            }),
            released: Some(2),
        }),
        Reply::Prices(PricesView {
            rows: vec![],
            ceiling: crate::spend::Ceiling::default(),
            spent: None,
            released: None,
        }),
        Reply::Attention(queue()),
        Reply::Ops(trail::ops()),
        Reply::Help(crate::boundary::help::rows(None)),
        Reply::Search(found()),
        // A search that matched nothing still knows its own question.
        Reply::Search(Found::default()),
        Reply::Config(ConfigAnswer::Lineages(vec![Lineage {
            branch: ConfigBranch {
                name: "main".into(),
                tip_oid: "abcdef1234".into(),
                tip_short_oid: "abcdef1".into(),
                tip_timestamp_unix: 1_700_000_000,
            },
            files: vec!["workflow.yaml".into()],
        }])),
        Reply::Config(ConfigAnswer::Models(vec!["opus".into(), "sonnet".into()])),
    ]);
    out.extend(config::answers());
    out.extend(routing());
    out
}

/// The routing leg's listing rows (bl-024b, bl-77be) — their own fn at the
/// clippy line budget, and the seam is real: these are the two replies the
/// worktree lane moved at PROTOCOL 2.
fn routing() -> Vec<Reply> {
    vec![
        // The follow-class read's answer at both of its arms (bl-024b): a hold
        // that ended with nothing, and one carrying work whose input must
        // survive the trip verbatim.
        Reply::Invocations(Vec::new()),
        Reply::Invocations(vec![crate::registry::mailbox::Invocation {
            id: "inv-1".into(),
            tool: "Bash".into(),
            input: serde_json::json!({"command": "ls -l", "timeout": 30}),
            cwd: None,
        }]),
        // The worktree lane's row (bl-77be): the subject's location crosses
        // to the machine that runs it.
        Reply::Invocations(vec![crate::registry::mailbox::Invocation {
            id: "inv-2".into(),
            tool: "bash".into(),
            input: serde_json::json!({"command": "printf made > out.txt"}),
            cwd: Some("/w/home/agents/c-1".into()),
        }]),
        // REMOTE §5's roster (bl-4e08): both presence arms, a client that
        // advertises and one that has not, and a schema deep enough that a
        // codec rebuilding it rather than carrying it verbatim would show.
        Reply::Clients(vec![
            crate::registry::roster::ClientRow {
                client: "laptop".into(),
                present: true,
                // The stamp rides when there is one and is absent when the
                // client has never connected — both shapes in one fixture
                // (bl-d542).
                last_seen: Some(1_700_000_000),
                tools: vec![
                    crate::registry::tools::Tool {
                        name: "Bash".into(),
                        description: "run a command".into(),
                        input_schema: serde_json::json!({
                            "type": "object",
                            "properties": {"command": {"type": "string", "minLength": 1}},
                            "required": ["command"],
                        }),
                        subject_cwd: false,
                    },
                    // The consenting element (bl-77be), beside the plain one.
                    crate::registry::tools::Tool {
                        name: "bash".into(),
                        description: "run a command in the conversation's cwd".into(),
                        input_schema: serde_json::json!({"type": "object"}),
                        subject_cwd: true,
                    },
                ],
            },
            crate::registry::roster::ClientRow {
                client: "phone".into(),
                present: false,
                tools: Vec::new(),
                last_seen: None,
            },
        ]),
        // The doctor's two shapes (bl-28f4): a passing row, whose remedy is
        // ABSENT, and a failing one carrying the act — the one difference a
        // seat renders differently, so a corpus that carried only one would
        // prove only half of it.
        Reply::Doctor(vec![
            crate::doctor::Row {
                check: "listener".into(),
                ok: true,
                fact: "listening on 127.0.0.1:7737".into(),
                remedy: None,
            },
            crate::doctor::Row {
                check: "address".into(),
                ok: false,
                fact: "127.0.0.1:0 is a request, not an endpoint".into(),
                remedy: Some("`WIRE_HOST=<host> WIRE_PORT=<port> yog wire-certs` states it".into()),
            },
        ]),
    ]
}