huskies: merge 962

This commit is contained in:
dave
2026-05-13 11:58:50 +00:00
parent 658e02c9b2
commit 184c214c34
19 changed files with 204 additions and 44 deletions
+2 -2
View File
@@ -312,7 +312,7 @@ pub(super) fn extract_item_view(item: &PipelineItemCrdt) -> Option<PipelineItemV
_ => return None,
};
let agent = match item.agent.view() {
JsonValue::String(s) if !s.is_empty() => Some(s),
JsonValue::String(s) if !s.is_empty() => s.parse::<crate::config::AgentName>().ok(),
_ => None,
};
let retry_count = match item.retry_count.view() {
@@ -584,7 +584,7 @@ mod tests {
assert_eq!(view.story_id, "40_story_view");
assert!(matches!(view.stage, crate::pipeline_state::Stage::Qa));
assert_eq!(view.name, "View Test");
assert_eq!(view.agent.as_deref(), Some("coder-1"));
assert_eq!(view.agent.map(|a| a.as_str()), Some("coder-1"));
assert_eq!(view.retry_count, 2u32);
assert_eq!(view.depends_on, vec![10u32, 20u32]);
}
+5 -5
View File
@@ -175,7 +175,7 @@ pub struct WorkItem {
/// out of all read paths) when this register is empty — a nameless item is
/// treated as malformed, not surfaced with an empty string.
pub(super) name: String,
pub(super) agent: Option<String>,
pub(super) agent: Option<crate::config::AgentName>,
/// Retry counter — `0` when the CRDT register is unset.
pub(super) retry_count: u32,
/// Dependency story numbers — empty `Vec` when the register is unset.
@@ -210,9 +210,9 @@ impl WorkItem {
&self.name
}
/// Agent name pinned to this item, or `None` when unset.
pub fn agent(&self) -> Option<&str> {
self.agent.as_deref()
/// Typed agent pinned to this item, or `None` when unset.
pub fn agent(&self) -> Option<crate::config::AgentName> {
self.agent
}
/// Retry counter. Returns `0` when the register is unset.
@@ -255,7 +255,7 @@ impl WorkItem {
story_id: impl Into<String>,
stage: crate::pipeline_state::Stage,
name: impl Into<String>,
agent: Option<String>,
agent: Option<crate::config::AgentName>,
retry_count: u32,
depends_on: Vec<u32>,
claim: Option<Claim>,
+2 -2
View File
@@ -147,7 +147,7 @@ pub fn set_name(story_id: &str, name: Option<&str>) -> bool {
/// other fields to be known.
///
/// Returns `true` if the item was found and the write was performed.
pub fn set_agent(story_id: &str, agent: Option<&str>) -> bool {
pub fn set_agent(story_id: &str, agent: Option<crate::config::AgentName>) -> bool {
let Some(state_mutex) = get_crdt() else {
return false;
};
@@ -157,7 +157,7 @@ pub fn set_agent(story_id: &str, agent: Option<&str>) -> bool {
let Some(&idx) = state.index.get(story_id) else {
return false;
};
let value = agent.unwrap_or("").to_string();
let value = agent.map(|a| a.as_str().to_string()).unwrap_or_default();
apply_and_persist(&mut state, |s| {
s.crdt.doc.items[idx].agent.set(value.clone())
});
+13 -7
View File
@@ -213,7 +213,7 @@ fn migrate_story_ids_to_numeric_preserves_stage_and_name() {
let item = read_item("45").expect("item must be accessible by numeric ID");
assert!(matches!(item.stage, crate::pipeline_state::Stage::Coding));
assert_eq!(item.name, "Crash Bug");
assert_eq!(item.agent.as_deref(), Some("coder-1"));
assert_eq!(item.agent.map(|a| a.as_str()), Some("coder-1"));
}
#[test]
@@ -356,12 +356,15 @@ fn set_agent_some_writes_name() {
None,
);
let found = set_agent("871_story_set_agent_write", Some("coder-1"));
let found = set_agent(
"871_story_set_agent_write",
Some(crate::config::AgentName::Coder1),
);
assert!(found, "set_agent should return true for an existing item");
let item = read_item("871_story_set_agent_write").expect("item must exist");
assert_eq!(
item.agent.as_deref(),
item.agent.map(|a| a.as_str()),
Some("coder-1"),
"agent should be written to CRDT register"
);
@@ -385,7 +388,7 @@ fn set_agent_none_clears_register() {
// Confirm agent is set.
let before = read_item("871_story_set_agent_clear").expect("item must exist");
assert_eq!(before.agent.as_deref(), Some("coder-2"));
assert_eq!(before.agent.map(|a| a.as_str()), Some("coder-2"));
// Clear it.
let found = set_agent("871_story_set_agent_clear", None);
@@ -393,8 +396,8 @@ fn set_agent_none_clears_register() {
let after = read_item("871_story_set_agent_clear").expect("item must exist");
assert!(
after.agent.as_deref().unwrap_or("").is_empty(),
"agent should be cleared (empty string) after set_agent(None)"
after.agent.is_none(),
"agent should be cleared after set_agent(None)"
);
}
@@ -402,7 +405,10 @@ fn set_agent_none_clears_register() {
fn set_agent_returns_false_for_unknown_story() {
init_for_test();
let found = set_agent("999_story_nonexistent", Some("coder-1"));
let found = set_agent(
"999_story_nonexistent",
Some(crate::config::AgentName::Coder1),
);
assert!(
!found,
"set_agent should return false when story is not in the CRDT"