use super::CoordinationStatus;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct StatusCombinedVerdict {
pub word: String,
pub reason: Option<&'static str>,
}
pub fn resolve_coordination_with_trust(
pre_override: CoordinationStatus,
blocked_by_trust: bool,
needs_checkpoint: bool,
) -> (CoordinationStatus, bool) {
let pre_override_clean = coordination_axis_clean(&pre_override, false);
let trust_override = blocked_by_trust && !needs_checkpoint;
let mask_as_trust = trust_override && pre_override_clean;
let coordination_status = if mask_as_trust {
CoordinationStatus::Blocked
} else {
pre_override
};
(coordination_status, mask_as_trust)
}
pub fn coordination_axis_clean(coordination: &CoordinationStatus, blocked_by_trust: bool) -> bool {
match coordination {
CoordinationStatus::Clean => true,
CoordinationStatus::Blocked => blocked_by_trust,
CoordinationStatus::Ahead
| CoordinationStatus::Diverged
| CoordinationStatus::MergeReady => false,
}
}
pub fn health_severity(thread_health: &str) -> u8 {
match thread_health {
"clean" => 0,
"needs_reconcile" | "git_branch_advanced" => 4,
"needs_init" | "needs_import" => 3,
"needs_checkpoint" => 2,
_ => 1,
}
}
pub fn coordination_severity(status: &CoordinationStatus) -> u8 {
match status {
CoordinationStatus::Clean => 0,
CoordinationStatus::Ahead | CoordinationStatus::MergeReady => 1,
CoordinationStatus::Diverged => 3,
CoordinationStatus::Blocked => 4,
}
}
pub fn combined_verdict_axes(
thread_health: &str,
coordination: &CoordinationStatus,
coordination_blocked_by_trust: bool,
) -> (bool, bool, Option<&'static str>) {
let health_clean = thread_health == "clean";
let coordination_clean = coordination_axis_clean(coordination, coordination_blocked_by_trust);
let reason = match (health_clean, coordination_clean) {
(true, true) => None,
(false, false) => Some("checkout health and thread coordination both need attention"),
(false, true) => Some("checkout health needs attention"),
(true, false) => Some("thread coordination needs attention"),
};
(health_clean, coordination_clean, reason)
}
pub fn human_thread_health(status: &str) -> String {
match status {
"needs_init" => "setup needed".to_string(),
"needs_import" => "setup needed".to_string(),
"git_branch_advanced" => "Git branch advanced outside Heddle".to_string(),
"needs_reconcile" => "Git/Heddle mismatch".to_string(),
"needs_checkpoint" => "checkpoint needed".to_string(),
"dirty_worktree" | "uncaptured" => "work in progress".to_string(),
other => other.to_string(),
}
}
pub fn coordination_label(coordination: &CoordinationStatus, blocked_by_trust: bool) -> String {
if matches!(coordination, CoordinationStatus::Blocked)
&& coordination_axis_clean(coordination, blocked_by_trust)
{
"work in progress".to_string()
} else {
coordination.to_string()
}
}
pub fn status_combined_verdict(
thread_health: &str,
coordination: CoordinationStatus,
coordination_blocked_by_trust: bool,
) -> StatusCombinedVerdict {
let (health_clean, coordination_clean, reason) =
combined_verdict_axes(thread_health, &coordination, coordination_blocked_by_trust);
if health_clean && coordination_clean {
return StatusCombinedVerdict {
word: "clean".to_string(),
reason: None,
};
}
let surface_health = !health_clean
&& (coordination_clean
|| health_severity(thread_health) >= coordination_severity(&coordination));
let word = if surface_health {
human_thread_health(thread_health)
} else {
coordination_label(&coordination, coordination_blocked_by_trust)
};
StatusCombinedVerdict { word, reason }
}
#[cfg(test)]
mod tests {
use super::*;
const ALL_COORDINATION_STATES: [CoordinationStatus; 5] = [
CoordinationStatus::Clean,
CoordinationStatus::Ahead,
CoordinationStatus::Diverged,
CoordinationStatus::Blocked,
CoordinationStatus::MergeReady,
];
#[test]
fn dirty_wip_combined_verdict_reason_is_health_only() {
for health in ["dirty_worktree", "uncaptured"] {
let (health_clean, coordination_clean, reason) =
combined_verdict_axes(health, &CoordinationStatus::Blocked, true);
assert!(!health_clean, "{health} is a non-clean health state");
assert!(
coordination_clean,
"{health}'s trust-derived Blocked is a health-signal encoding → coordination effectively clean"
);
assert!(
coordination_axis_clean(&CoordinationStatus::Blocked, true),
"{health}: trust-derived Blocked must mask (work in progress)"
);
assert_eq!(
reason,
Some("checkout health needs attention"),
"{health}: reason must be health-only, not a coordination/both warning"
);
let reason = reason.unwrap();
assert!(
!reason.contains("coordination") && !reason.contains("both need attention"),
"{health}: reason must not mention coordination: {reason}"
);
}
}
#[test]
fn trust_blocked_combined_verdict_reason_is_health_only() {
let (_, coordination_clean, reason) =
combined_verdict_axes("git_branch_advanced", &CoordinationStatus::Blocked, true);
assert!(coordination_clean);
assert_eq!(reason, Some("checkout health needs attention"));
}
#[test]
fn genuine_blocked_surfaces_even_when_worktree_dirty() {
for health in ["dirty_worktree", "uncaptured"] {
assert!(
!coordination_axis_clean(&CoordinationStatus::Blocked, false),
"{health}: a genuine (non-trust) Blocked must never mask, even when health is dirty"
);
let (health_clean, coordination_clean, reason) =
combined_verdict_axes(health, &CoordinationStatus::Blocked, false);
assert!(!health_clean, "{health} is a non-clean health state");
assert!(
!coordination_clean,
"{health}: a genuine inter-thread Blocked is a real coordination block"
);
assert_eq!(
reason,
Some("checkout health and thread coordination both need attention"),
"{health}: the verdict reason must name the coordination block, not just health"
);
assert!(
reason.unwrap().contains("coordination"),
"{health}: reason must surface coordination: {reason:?}"
);
}
}
#[test]
fn genuine_coordination_states_still_surface() {
for coordination in [
CoordinationStatus::Ahead,
CoordinationStatus::Diverged,
CoordinationStatus::MergeReady,
CoordinationStatus::Blocked,
] {
assert!(
!coordination_axis_clean(&coordination, false),
"{coordination:?} as a genuine (non-trust) state is never clean"
);
let (health_clean, coordination_clean, reason) =
combined_verdict_axes("clean", &coordination, false);
assert!(health_clean && !coordination_clean);
assert_eq!(
reason,
Some("thread coordination needs attention"),
"{coordination:?}: combined verdict must name coordination"
);
}
}
#[test]
fn both_axes_clean_verdict_has_no_reason() {
let (health_clean, coordination_clean, reason) =
combined_verdict_axes("clean", &CoordinationStatus::Clean, false);
assert!(health_clean && coordination_clean);
assert_eq!(reason, None);
let verdict = status_combined_verdict("clean", CoordinationStatus::Clean, false);
assert_eq!(verdict.word, "clean");
assert_eq!(verdict.reason, None);
}
#[test]
fn coordination_provenance_survives_trust_override_across_all_states() {
for pre_override in ALL_COORDINATION_STATES {
let genuinely_clean = coordination_axis_clean(&pre_override, false);
for &trust_verified in &[true, false] {
let blocked_by_trust = !trust_verified;
let (coordination, blocked_by_trust_only) =
resolve_coordination_with_trust(pre_override, blocked_by_trust, false);
let health = if trust_verified {
"clean"
} else {
"dirty_worktree"
};
let (health_clean, coordination_clean, reason) =
combined_verdict_axes(health, &coordination, blocked_by_trust_only);
let label = coordination_label(&coordination, blocked_by_trust_only);
let ctx = format!("{pre_override:?} / trust_verified={trust_verified}");
assert_eq!(
health_clean, trust_verified,
"{ctx}: health axis cleanliness"
);
if genuinely_clean {
assert!(
coordination_clean,
"{ctx}: a genuinely-clean axis stays effectively clean"
);
if trust_verified {
assert_eq!(reason, None, "{ctx}: all-clean → no reason");
assert_eq!(label, "clean", "{ctx}: clean axis renders as clean");
} else {
assert_eq!(
reason,
Some("checkout health needs attention"),
"{ctx}: clean axis + dirty worktree → health-only WIP (coordination masked)"
);
assert_eq!(
label, "work in progress",
"{ctx}: a sole-trust-derived Blocked renders as WIP, never a coordination state"
);
}
} else {
assert_eq!(
coordination, pre_override,
"{ctx}: a genuine non-clean state must be preserved, not re-stamped to Blocked"
);
assert!(
!blocked_by_trust_only,
"{ctx}: a genuine non-clean axis is never marked trust-only/maskable"
);
assert!(
!coordination_clean,
"{ctx}: a genuine non-clean axis must surface, even with a dirty worktree"
);
let reason = reason.expect("a non-clean axis always yields a verdict reason");
assert!(
reason.contains("coordination"),
"{ctx}: the default verdict reason must name coordination: {reason}"
);
if !trust_verified {
assert_eq!(
reason, "checkout health and thread coordination both need attention",
"{ctx}: dirty worktree + genuine coordination state → BOTH axes surface"
);
}
assert_eq!(
label,
pre_override.to_string(),
"{ctx}: -v must show the genuine Coordination state, not the WIP mask"
);
assert_ne!(
label, "work in progress",
"{ctx}: a genuine coordination state must never be hidden behind WIP"
);
}
}
}
}
#[test]
fn needs_checkpoint_suppresses_the_trust_override() {
let (coordination, blocked_by_trust_only) =
resolve_coordination_with_trust(CoordinationStatus::Blocked, true, true);
assert!(matches!(coordination, CoordinationStatus::Blocked));
assert!(
!blocked_by_trust_only,
"needs_checkpoint suppresses the override; genuine block wins"
);
let (coordination, blocked_by_trust_only) =
resolve_coordination_with_trust(CoordinationStatus::Clean, true, true);
assert!(
matches!(coordination, CoordinationStatus::Clean),
"no override → axis stays clean"
);
assert!(!blocked_by_trust_only);
}
#[test]
fn status_combined_verdict_surfaces_more_severe_axis() {
let health_only = status_combined_verdict(
"dirty_worktree",
CoordinationStatus::Blocked,
true, );
assert_eq!(health_only.word, "work in progress");
assert_eq!(health_only.reason, Some("checkout health needs attention"));
let coord_only = status_combined_verdict("clean", CoordinationStatus::Diverged, false);
assert_eq!(coord_only.word, "diverged");
assert_eq!(
coord_only.reason,
Some("thread coordination needs attention")
);
}
}