huskies: merge 864
This commit is contained in:
@@ -57,7 +57,12 @@ mod tests {
|
||||
.unwrap();
|
||||
// Place the story in 2_current/ via CRDT (the only source of truth).
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("story-3", "2_current", "---\nname: Story 3\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"story-3",
|
||||
"2_current",
|
||||
"---\nname: Story 3\n---\n",
|
||||
crate::db::ItemMeta::named("Story 3"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
// No agents are running — coder-1 is free.
|
||||
@@ -139,6 +144,11 @@ mod tests {
|
||||
"9930_story_qa1",
|
||||
"3_qa",
|
||||
"---\nname: QA Story\nagent: coder-1\n---\n",
|
||||
crate::db::ItemMeta {
|
||||
name: Some("QA Story".into()),
|
||||
agent: Some("coder-1".into()),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -188,6 +198,11 @@ mod tests {
|
||||
"story-pref",
|
||||
"2_current",
|
||||
"---\nname: Coder Story\nagent: coder-1\n---\n",
|
||||
crate::db::ItemMeta {
|
||||
name: Some("Coder Story".into()),
|
||||
agent: Some("coder-1".into()),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -235,6 +250,11 @@ mod tests {
|
||||
"9931_story_noqa",
|
||||
"3_qa",
|
||||
"---\nname: QA Story No Agent\nagent: coder-1\n---\n",
|
||||
crate::db::ItemMeta {
|
||||
name: Some("QA Story No Agent".into()),
|
||||
agent: Some("coder-1".into()),
|
||||
..Default::default()
|
||||
},
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -274,6 +294,7 @@ mod tests {
|
||||
"9932_story_waiting",
|
||||
"2_current",
|
||||
"---\nname: Waiting\ndepends_on: [9999]\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Waiting\ndepends_on: [9999]\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -307,12 +328,18 @@ mod tests {
|
||||
// Seed stories via CRDT (the only source of truth).
|
||||
crate::db::ensure_content_store();
|
||||
// Dep 999 is now done.
|
||||
crate::db::write_item_with_content("999_story_dep", "5_done", "---\nname: Dep\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"999_story_dep",
|
||||
"5_done",
|
||||
"---\nname: Dep\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Dep\n---\n"),
|
||||
);
|
||||
// Story 10 depends on 999 which is done.
|
||||
crate::db::write_item_with_content(
|
||||
"10_story_unblocked",
|
||||
"2_current",
|
||||
"---\nname: Unblocked\ndepends_on: [999]\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Unblocked\ndepends_on: [999]\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -496,6 +523,9 @@ mod tests {
|
||||
"9860_story_conflict",
|
||||
"4_merge",
|
||||
"---\nname: Conflict\nmerge_failure: \"CONFLICT (content): server/src/lib.rs\"\n---\n",
|
||||
crate::db::ItemMeta::from_yaml(
|
||||
"---\nname: Conflict\nmerge_failure: \"CONFLICT (content): server/src/lib.rs\"\n---\n",
|
||||
),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -530,6 +560,9 @@ mod tests {
|
||||
"9861_story_nothing",
|
||||
"4_merge",
|
||||
"---\nname: Nothing\nmerge_failure: \"nothing to commit, working tree clean\"\n---\n",
|
||||
crate::db::ItemMeta::from_yaml(
|
||||
"---\nname: Nothing\nmerge_failure: \"nothing to commit, working tree clean\"\n---\n",
|
||||
),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -565,6 +598,9 @@ mod tests {
|
||||
"9863_story_blocked_conflict",
|
||||
"4_merge",
|
||||
"---\nname: Blocked conflict\nmerge_failure: \"CONFLICT (content): foo.rs\"\nblocked: true\n---\n",
|
||||
crate::db::ItemMeta::from_yaml(
|
||||
"---\nname: Blocked conflict\nmerge_failure: \"CONFLICT (content): foo.rs\"\nblocked: true\n---\n",
|
||||
),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -599,6 +635,9 @@ mod tests {
|
||||
"9862_story_attempted",
|
||||
"4_merge",
|
||||
"---\nname: Already tried\nmerge_failure: \"CONFLICT (content): foo.rs\"\nmergemaster_attempted: true\n---\n",
|
||||
crate::db::ItemMeta::from_yaml(
|
||||
"---\nname: Already tried\nmerge_failure: \"CONFLICT (content): foo.rs\"\nmergemaster_attempted: true\n---\n",
|
||||
),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
|
||||
@@ -83,7 +83,12 @@ impl AgentPool {
|
||||
&contents,
|
||||
);
|
||||
crate::db::write_content(story_id, &updated);
|
||||
crate::db::write_item_with_content(story_id, "4_merge", &updated);
|
||||
crate::db::write_item_with_content(
|
||||
story_id,
|
||||
"4_merge",
|
||||
&updated,
|
||||
crate::db::ItemMeta::from_yaml(&updated),
|
||||
);
|
||||
}
|
||||
crate::crdt_state::set_mergemaster_attempted(story_id, true);
|
||||
if let Err(e) = self
|
||||
|
||||
@@ -168,6 +168,7 @@ mod tests {
|
||||
"9970_story_archived",
|
||||
"6_archived",
|
||||
"---\nname: Archived\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Archived\n---\n"),
|
||||
);
|
||||
|
||||
// Also place a stale .md file in a temp 1_backlog/ dir.
|
||||
@@ -200,9 +201,24 @@ mod tests {
|
||||
fn scan_stage_items_returns_sorted_story_ids() {
|
||||
// Write items via the CRDT store (the primary source of truth).
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("9942_story_foo", "2_current", "---\nname: foo\n---");
|
||||
crate::db::write_item_with_content("9940_story_bar", "2_current", "---\nname: bar\n---");
|
||||
crate::db::write_item_with_content("9935_story_baz", "2_current", "---\nname: baz\n---");
|
||||
crate::db::write_item_with_content(
|
||||
"9942_story_foo",
|
||||
"2_current",
|
||||
"---\nname: foo\n---",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: foo\n---"),
|
||||
);
|
||||
crate::db::write_item_with_content(
|
||||
"9940_story_bar",
|
||||
"2_current",
|
||||
"---\nname: bar\n---",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: bar\n---"),
|
||||
);
|
||||
crate::db::write_item_with_content(
|
||||
"9935_story_baz",
|
||||
"2_current",
|
||||
"---\nname: baz\n---",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: baz\n---"),
|
||||
);
|
||||
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let items = scan_stage_items(tmp.path(), "2_current");
|
||||
|
||||
@@ -188,6 +188,9 @@ mod tests {
|
||||
"10_spike_research",
|
||||
"3_qa",
|
||||
"---\nname: Research spike\nreview_hold: true\n---\n# Spike\n",
|
||||
crate::db::ItemMeta::from_yaml(
|
||||
"---\nname: Research spike\nreview_hold: true\n---\n# Spike\n",
|
||||
),
|
||||
);
|
||||
assert!(has_review_hold(tmp.path(), "3_qa", "10_spike_research"));
|
||||
}
|
||||
|
||||
@@ -88,7 +88,12 @@ pub(super) fn write_review_hold_to_store(story_id: &str) {
|
||||
.flatten()
|
||||
.map(|i| i.stage.dir_name().to_string())
|
||||
.unwrap_or_else(|| "3_qa".to_string());
|
||||
crate::db::write_item_with_content(story_id, &stage, &updated);
|
||||
crate::db::write_item_with_content(
|
||||
story_id,
|
||||
&stage,
|
||||
&updated,
|
||||
crate::db::ItemMeta::from_yaml(&updated),
|
||||
);
|
||||
} else {
|
||||
slog_error!("[pipeline] Cannot write review_hold for '{story_id}': no content in store");
|
||||
}
|
||||
|
||||
@@ -172,7 +172,12 @@ async fn pipeline_advance_sends_agent_state_changed_to_watcher_tx() {
|
||||
|
||||
// Seed story via CRDT (the only source of truth).
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("173_story_test", "2_current", "---\nname: test\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"173_story_test",
|
||||
"2_current",
|
||||
"---\nname: test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: test\n---\n"),
|
||||
);
|
||||
|
||||
// Write a project.toml with a qa agent so start_agent can resolve it.
|
||||
fs::create_dir_all(root.join(".huskies")).unwrap();
|
||||
|
||||
@@ -51,6 +51,7 @@ async fn mergemaster_blocks_and_sends_story_blocked_when_no_commits_ahead() {
|
||||
"9919_story_no_commits",
|
||||
"2_current",
|
||||
"---\nname: Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Test\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -145,11 +146,13 @@ stage = "qa"
|
||||
"292_story_first",
|
||||
"3_qa",
|
||||
"---\nname: First\nqa: human\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: First\nqa: human\n---\n"),
|
||||
);
|
||||
crate::db::write_item_with_content(
|
||||
"293_story_second",
|
||||
"3_qa",
|
||||
"---\nname: Second\nqa: human\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Second\nqa: human\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
@@ -245,7 +248,12 @@ async fn stale_mergemaster_advance_for_done_story_is_noop() {
|
||||
let story_id = "9929_story_zombie_merge";
|
||||
let content = "---\nname: Zombie Merge Test\n---\n";
|
||||
crate::db::write_content(story_id, content);
|
||||
crate::db::write_item_with_content(story_id, "5_done", content);
|
||||
crate::db::write_item_with_content(
|
||||
story_id,
|
||||
"5_done",
|
||||
content,
|
||||
crate::db::ItemMeta::from_yaml(content),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
let mut rx = pool.watcher_tx.subscribe();
|
||||
@@ -381,6 +389,7 @@ async fn work_survived_advances_to_qa_instead_of_blocking() {
|
||||
"9945_story_survived",
|
||||
"2_current",
|
||||
"---\nname: Survived Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Survived Test\n---\n"),
|
||||
);
|
||||
|
||||
// Simulate a passing run_tests call during the agent's session (bug 668):
|
||||
@@ -474,6 +483,7 @@ async fn no_committed_work_still_retries_and_blocks() {
|
||||
"9946_story_nowork",
|
||||
"2_current",
|
||||
"---\nname: No Work Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: No Work Test\n---\n"),
|
||||
);
|
||||
|
||||
// Write a project.toml with max_retries = 1.
|
||||
@@ -601,6 +611,7 @@ async fn gates_failed_no_test_evidence_does_not_advance() {
|
||||
"9947_story_no_evidence",
|
||||
"2_current",
|
||||
"---\nname: No Evidence Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: No Evidence Test\n---\n"),
|
||||
);
|
||||
|
||||
// Explicitly ensure no test evidence exists for this story.
|
||||
@@ -730,6 +741,7 @@ async fn gates_failed_with_test_evidence_and_committed_work_advances() {
|
||||
"9948_story_with_evidence",
|
||||
"2_current",
|
||||
"---\nname: With Evidence Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: With Evidence Test\n---\n"),
|
||||
);
|
||||
|
||||
// Write the run_tests evidence — simulates the agent having called run_tests
|
||||
@@ -813,6 +825,7 @@ stage = "coder"
|
||||
"9950_story_warm_resume",
|
||||
"2_current",
|
||||
"---\nname: Warm Resume Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Warm Resume Test\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
|
||||
@@ -651,6 +651,7 @@ async fn server_side_merge_happy_path_advances_to_done() {
|
||||
"757a_happy",
|
||||
"4_merge",
|
||||
"---\nname: Happy path test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Happy path test\n---\n"),
|
||||
);
|
||||
|
||||
let pool = Arc::new(AgentPool::new_test(3001));
|
||||
@@ -787,6 +788,7 @@ async fn server_side_merge_conflict_sets_merge_failure() {
|
||||
"757b_conflict",
|
||||
"4_merge",
|
||||
"---\nname: Conflict test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Conflict test\n---\n"),
|
||||
);
|
||||
|
||||
let pool = Arc::new(AgentPool::new_test(3001));
|
||||
@@ -898,6 +900,7 @@ async fn server_side_merge_gate_failure_sets_merge_failure() {
|
||||
"757c_gates",
|
||||
"4_merge",
|
||||
"---\nname: Gate failure test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Gate failure test\n---\n"),
|
||||
);
|
||||
|
||||
let pool = Arc::new(AgentPool::new_test(3001));
|
||||
|
||||
@@ -597,7 +597,12 @@ mod tests {
|
||||
crate::db::ensure_content_store();
|
||||
|
||||
let story_id = "9960_story_gate_injection_881";
|
||||
crate::db::write_item_with_content(story_id, "2_current", "---\nname: Test\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
story_id,
|
||||
"2_current",
|
||||
"---\nname: Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Test\n---\n"),
|
||||
);
|
||||
crate::crdt_state::set_retry_count(story_id, 1);
|
||||
|
||||
let gate_output =
|
||||
@@ -630,7 +635,12 @@ mod tests {
|
||||
crate::db::ensure_content_store();
|
||||
|
||||
let story_id = "9961_story_no_gate_injection_881";
|
||||
crate::db::write_item_with_content(story_id, "2_current", "---\nname: Test\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
story_id,
|
||||
"2_current",
|
||||
"---\nname: Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Test\n---\n"),
|
||||
);
|
||||
// retry_count is 0 (default — never bumped).
|
||||
|
||||
crate::db::write_content(&format!("{story_id}:gate_output"), "some previous output");
|
||||
@@ -690,7 +700,12 @@ mod tests {
|
||||
crate::db::ensure_content_store();
|
||||
|
||||
let story_id = "9962_story_abort_respawn_882";
|
||||
crate::db::write_item_with_content(story_id, "2_current", "---\nname: Test\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
story_id,
|
||||
"2_current",
|
||||
"---\nname: Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Test\n---\n"),
|
||||
);
|
||||
|
||||
let db_key = format!("{story_id}:abort_respawn_count");
|
||||
const CAP: u32 = 5;
|
||||
|
||||
@@ -429,7 +429,12 @@ async fn start_agent_rejects_mergemaster_on_coding_stage_story() {
|
||||
)
|
||||
.unwrap();
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("310_story_foo", "2_current", "---\nname: Foo\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"310_story_foo",
|
||||
"2_current",
|
||||
"---\nname: Foo\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Foo\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3099);
|
||||
let result = pool
|
||||
@@ -463,7 +468,12 @@ async fn start_agent_rejects_coder_on_qa_stage_story() {
|
||||
)
|
||||
.unwrap();
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("8842_story_qa_guard", "3_qa", "---\nname: QA Guard\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"8842_story_qa_guard",
|
||||
"3_qa",
|
||||
"---\nname: QA Guard\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: QA Guard\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3099);
|
||||
let result = pool
|
||||
@@ -497,7 +507,12 @@ async fn start_agent_rejects_qa_on_merge_stage_story() {
|
||||
)
|
||||
.unwrap();
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("55_story_baz", "4_merge", "---\nname: Baz\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"55_story_baz",
|
||||
"4_merge",
|
||||
"---\nname: Baz\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Baz\n---\n"),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3099);
|
||||
let result = pool
|
||||
|
||||
@@ -143,7 +143,12 @@ mod tests {
|
||||
let story_content = "test";
|
||||
fs::write(current.join("60_story_cleanup.md"), story_content).unwrap();
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("60_story_cleanup", "2_current", story_content);
|
||||
crate::db::write_item_with_content(
|
||||
"60_story_cleanup",
|
||||
"2_current",
|
||||
story_content,
|
||||
crate::db::ItemMeta::from_yaml(story_content),
|
||||
);
|
||||
|
||||
let pool = AgentPool::new_test(3001);
|
||||
pool.inject_test_agent("60_story_cleanup", "coder-1", AgentStatus::Completed);
|
||||
|
||||
@@ -42,7 +42,12 @@ mod tests {
|
||||
#[test]
|
||||
fn find_active_story_stage_detects_current() {
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("10_story_test", "2_current", "---\nname: Test\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"10_story_test",
|
||||
"2_current",
|
||||
"---\nname: Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Test\n---\n"),
|
||||
);
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
assert!(matches!(
|
||||
find_active_story_stage(tmp.path(), "10_story_test"),
|
||||
@@ -53,7 +58,12 @@ mod tests {
|
||||
#[test]
|
||||
fn find_active_story_stage_detects_qa() {
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("11_story_test", "3_qa", "---\nname: Test\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"11_story_test",
|
||||
"3_qa",
|
||||
"---\nname: Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Test\n---\n"),
|
||||
);
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
assert!(matches!(
|
||||
find_active_story_stage(tmp.path(), "11_story_test"),
|
||||
@@ -64,7 +74,12 @@ mod tests {
|
||||
#[test]
|
||||
fn find_active_story_stage_detects_merge() {
|
||||
crate::db::ensure_content_store();
|
||||
crate::db::write_item_with_content("12_story_test", "4_merge", "---\nname: Test\n---\n");
|
||||
crate::db::write_item_with_content(
|
||||
"12_story_test",
|
||||
"4_merge",
|
||||
"---\nname: Test\n---\n",
|
||||
crate::db::ItemMeta::from_yaml("---\nname: Test\n---\n"),
|
||||
);
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
assert!(matches!(
|
||||
find_active_story_stage(tmp.path(), "12_story_test"),
|
||||
|
||||
Reference in New Issue
Block a user