//! The barrier round: gather due people → dispatch LLM jobs → freeze → //! collect every result → apply all actions → advance sim clock. //! //! Day cycle: 09:00 standup (everyone woken, manager assigns) → work blocks //! → 12:00 lunch → 17:00 next day. use bevy::prelude::*; use std::collections::HashSet; use crate::company::{CompanyCfg, Workspace, WriteKind}; use crate::llm::{ system_prompt, write_prompts, Action, DecisionResult, Job, JobResult, LlmPool, }; use crate::people::{BossNotes, Bubble, Memory, Names, Person, Walking}; use crate::scene::{flat, Spots}; use crate::sim::*; use crate::tasks::{find_person_name, TaskBoard, TaskStatus}; /// Resolve a person reference from the model: "Manager"/"boss" maps to the /// manager, otherwise fuzzy name matching. /// "boss"/"you"/"user" → the human behind the keyboard. fn resolve_target(cfg: &CompanyCfg, given: &str) -> Option { let low = given.trim().to_lowercase(); if low == "boss" || low == "user" || low == "me (the boss)" || low == "the boss" { return Some("__boss__".into()); } if let Some(hit) = find_person_name(cfg.people.iter().map(|p| p.name.as_str()), given) { return Some(hit); } let g = given.trim().to_lowercase(); if g.contains("manager") || g == "boss" || g.contains("lead") && g.contains("the") { return cfg.people.iter().find(|p| p.is_manager).map(|p| p.name.clone()); } None } /// Kick off a new round if the barrier is open and anyone is due. pub fn gather_due( time: Res