yog 0.0.2

yog: a balls-oriented session manager for lernie loops (egui frontend)
Documentation
//! The shell's reads of the world clock and its entropy (§7.2, §4.2): the
//! three mintings that can only happen at the process boundary, in one place
//! because each is a fact two seats must agree on. The frame takes them as
//! parameters and stays testable; nothing here is derived, cached, or held.

/// An entropy seed for the conversation-mint RNG (§3.3), held stable in
/// [`StartState::mint_seed`] so the composer's preview and its fire agree —
/// **per prediction, not per session**: a landed fire spends its seed and draws
/// the next one here ([`StartState::spend_mint`], bl-28ba). Not
/// secret — the mint is collision-avoidance, and the occupied-set check is what
/// guarantees uniqueness (mirrors `names::SplitMix64::from_entropy`).
pub(crate) fn entropy_seed() -> u64 {
    let nanos = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map_or(0, |d| d.as_nanos() as u64);
    nanos ^ (u64::from(std::process::id()) << 32)
}

/// The wall-clock `ops.jsonl` timestamp (§4.2) for the verb dispatchers, which
/// stay clock-free and testable by taking it as a parameter. Delegated to the
/// crate's one time seam ([`Clock::stamp`](crate::ui_state::Clock::stamp)) —
/// the §7.2 worker writes its own ops lines from the *injected* clock, and two
/// spellings of "now, as a string" would be two facts.
pub fn now_ts() -> String {
    crate::ui_state::Clock::stamp(&crate::ui_state::SystemClock)
}

/// Wall-clock unix seconds for every seat that dates something (§11): the
/// conversation list's ages and the in-flight strip's elapsed (§5.1 #28). Minted
/// here at the shell boundary like [`now_ts`], in **one** place — two spellings
/// of "now, in seconds" would be two facts, and the two seats must agree on what
/// `42s` means.
pub(crate) fn now_unix() -> i64 {
    std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map_or(0, |d| i64::try_from(d.as_secs()).unwrap_or(i64::MAX))
}