huskies: merge 945
This commit is contained in:
@@ -92,7 +92,6 @@ pub(crate) fn tool_dump_crdt(args: &Value) -> Result<String, String> {
|
||||
"name": item.name,
|
||||
"agent": item.agent,
|
||||
"retry_count": item.retry_count,
|
||||
"blocked": item.blocked,
|
||||
"depends_on": item.depends_on,
|
||||
"claimed_by": item.claimed_by,
|
||||
"claimed_at": item.claimed_at,
|
||||
|
||||
@@ -291,7 +291,6 @@ mod tests {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let ctx = test_ctx(tmp.path());
|
||||
@@ -318,7 +317,6 @@ mod tests {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let tmp = tempfile::tempdir().unwrap();
|
||||
let ctx = test_ctx(tmp.path());
|
||||
|
||||
@@ -54,8 +54,16 @@ pub(super) async fn tool_approve_qa(args: &Value, ctx: &AppContext) -> Result<St
|
||||
|
||||
let project_root = ctx.services.agents.get_project_root(&ctx.state)?;
|
||||
|
||||
// Clear review_hold before moving (story 932: CRDT register).
|
||||
crate::crdt_state::set_review_hold(story_id, false);
|
||||
// Clear review_hold before moving (story 945: Stage::ReviewHold variant).
|
||||
if let Ok(Some(item)) = crate::pipeline_state::read_typed(story_id)
|
||||
&& matches!(item.stage, crate::pipeline_state::Stage::ReviewHold { .. })
|
||||
{
|
||||
let _ = crate::pipeline_state::apply_transition_str(
|
||||
story_id,
|
||||
crate::pipeline_state::PipelineEvent::ReviewHoldCleared,
|
||||
None,
|
||||
);
|
||||
}
|
||||
|
||||
if is_spike(story_id) {
|
||||
// Spikes skip the merge stage entirely: merge the feature branch to master
|
||||
|
||||
@@ -183,9 +183,6 @@ pub(super) async fn tool_status(args: &Value, ctx: &AppContext) -> Result<String
|
||||
if let Some(agent) = view.agent() {
|
||||
front_matter.insert("agent".to_string(), json!(agent));
|
||||
}
|
||||
if view.blocked() {
|
||||
front_matter.insert("blocked".to_string(), json!(true));
|
||||
}
|
||||
if let Some(qa) = view.qa_mode() {
|
||||
front_matter.insert("qa".to_string(), json!(qa));
|
||||
}
|
||||
@@ -216,14 +213,6 @@ pub(super) async fn tool_status(args: &Value, ctx: &AppContext) -> Result<String
|
||||
front_matter.insert("merge_failure".to_string(), json!(mf));
|
||||
}
|
||||
|
||||
// review_hold is a typed CRDT register (story 932).
|
||||
if crate::crdt_state::read_item(story_id)
|
||||
.map(|v| v.review_hold())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
front_matter.insert("review_hold".to_string(), json!(true));
|
||||
}
|
||||
|
||||
// --- AC checklist ---
|
||||
let ac_items: Vec<Value> = parse_ac_items(&contents)
|
||||
.into_iter()
|
||||
@@ -357,7 +346,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn tool_status_returns_blocked_retry_count_and_depends_on() {
|
||||
async fn tool_status_returns_retry_count_and_depends_on() {
|
||||
let tmp = tempdir().unwrap();
|
||||
|
||||
crate::crdt_state::init_for_test();
|
||||
@@ -369,7 +358,6 @@ mod tests {
|
||||
story_content,
|
||||
crate::db::ItemMeta::named("Blocked Story"),
|
||||
);
|
||||
crate::crdt_state::set_blocked("9887_story_blocked_test", true);
|
||||
crate::crdt_state::set_retry_count("9887_story_blocked_test", 3);
|
||||
crate::crdt_state::set_depends_on("9887_story_blocked_test", &[100, 200]);
|
||||
|
||||
@@ -379,7 +367,6 @@ mod tests {
|
||||
.unwrap();
|
||||
let parsed: serde_json::Value = serde_json::from_str(&result).unwrap();
|
||||
|
||||
assert_eq!(parsed["front_matter"]["blocked"], true);
|
||||
assert_eq!(parsed["front_matter"]["retry_count"], 3);
|
||||
let depends_on = parsed["front_matter"]["depends_on"].as_array().unwrap();
|
||||
assert_eq!(depends_on.len(), 2);
|
||||
|
||||
@@ -127,20 +127,20 @@ pub(crate) fn tool_show_epic(args: &Value, _ctx: &AppContext) -> Result<String,
|
||||
continue;
|
||||
};
|
||||
if member_view.epic() == Some(epic_id) {
|
||||
// Frozen is now an orthogonal CRDT flag (story 934, stage 4).
|
||||
let stage_name = if member_view.frozen() {
|
||||
"frozen"
|
||||
} else {
|
||||
match &item.stage {
|
||||
Stage::Upcoming | Stage::Backlog => "backlog",
|
||||
Stage::Coding => "current",
|
||||
Stage::Qa => "qa",
|
||||
Stage::Merge { .. } => "merge",
|
||||
Stage::Done { .. } => "done",
|
||||
Stage::Archived { .. } => "archived",
|
||||
Stage::MergeFailure { .. } => "merge_failure",
|
||||
Stage::Blocked { .. } => "blocked",
|
||||
}
|
||||
// Story 945: Frozen / ReviewHold / MergeFailureFinal are first-class
|
||||
// Stage variants — no more orthogonal boolean flags.
|
||||
let stage_name = match &item.stage {
|
||||
Stage::Upcoming | Stage::Backlog => "backlog",
|
||||
Stage::Coding => "current",
|
||||
Stage::Qa => "qa",
|
||||
Stage::Merge { .. } => "merge",
|
||||
Stage::Done { .. } => "done",
|
||||
Stage::Archived { .. } => "archived",
|
||||
Stage::MergeFailure { .. } => "merge_failure",
|
||||
Stage::MergeFailureFinal { .. } => "merge_failure_final",
|
||||
Stage::Blocked { .. } => "blocked",
|
||||
Stage::Frozen { .. } => "frozen",
|
||||
Stage::ReviewHold { .. } => "review_hold",
|
||||
};
|
||||
if matches!(item.stage, Stage::Done { .. }) {
|
||||
done += 1;
|
||||
|
||||
@@ -91,12 +91,30 @@ pub(crate) fn tool_update_story(args: &Value, ctx: &AppContext) -> Result<String
|
||||
}
|
||||
}
|
||||
"review_hold" => {
|
||||
if let Some(b) = value.as_bool() {
|
||||
crate::crdt_state::set_review_hold(story_id, b);
|
||||
} else if value.as_str() == Some("true") {
|
||||
crate::crdt_state::set_review_hold(story_id, true);
|
||||
} else if value.as_str() == Some("false") {
|
||||
crate::crdt_state::set_review_hold(story_id, false);
|
||||
let want_hold = match value {
|
||||
Value::Bool(b) => Some(*b),
|
||||
Value::String(s) if s == "true" => Some(true),
|
||||
Value::String(s) if s == "false" => Some(false),
|
||||
_ => None,
|
||||
};
|
||||
match want_hold {
|
||||
Some(true) => {
|
||||
crate::pipeline_state::apply_transition_str(
|
||||
story_id,
|
||||
crate::pipeline_state::PipelineEvent::ReviewHold {
|
||||
reason: "Set via update_story".to_string(),
|
||||
},
|
||||
None,
|
||||
)?;
|
||||
}
|
||||
Some(false) => {
|
||||
crate::pipeline_state::apply_transition_str(
|
||||
story_id,
|
||||
crate::pipeline_state::PipelineEvent::ReviewHoldCleared,
|
||||
None,
|
||||
)?;
|
||||
}
|
||||
None => {}
|
||||
}
|
||||
}
|
||||
"frozen" => {
|
||||
@@ -126,8 +144,12 @@ pub(crate) fn tool_update_story(args: &Value, ctx: &AppContext) -> Result<String
|
||||
}
|
||||
}
|
||||
"mergemaster_attempted" => {
|
||||
if let Some(b) = value.as_bool() {
|
||||
crate::crdt_state::set_mergemaster_attempted(story_id, b);
|
||||
if let Some(true) = value.as_bool() {
|
||||
crate::pipeline_state::apply_transition_str(
|
||||
story_id,
|
||||
crate::pipeline_state::PipelineEvent::MergemasterAttempted,
|
||||
None,
|
||||
)?;
|
||||
}
|
||||
}
|
||||
other => {
|
||||
|
||||
Reference in New Issue
Block a user