huskies: merge 491_story_watcher_fires_on_crdt_state_transitions_instead_of_filesystem_events

This commit is contained in:
dave
2026-04-08 01:14:55 +00:00
parent dbdcf334aa
commit 5c2769dd7d
6 changed files with 272 additions and 58 deletions
+3 -2
View File
@@ -65,8 +65,9 @@ fn move_item<'a>(
}
}
// TODO(491): Wire up CRDT state transitions once the watcher story lands.
// crate::db::crdt::crdt_write(story_id, target_dir, &target_path);
// Write state through CRDT ops (and legacy shadow table) so subscribers
// are notified of the stage transition without relying on the filesystem watcher.
crate::db::shadow_write(story_id, target_dir, &target_path);
slog!("[lifecycle] Moved '{story_id}' from work/{src_dir}/ to work/{target_dir}/");
Ok(Some(src_dir))
@@ -60,12 +60,23 @@ pub(super) fn is_story_blocked(project_root: &Path, stage_dir: &str, story_id: &
/// Return `true` if the story has any `depends_on` entries that are not yet in
/// `5_done` or `6_archived`.
///
/// Auto-assign calls this to hold back stories whose dependencies haven't landed.
/// Reads dependency state from the CRDT document first. Falls back to the
/// filesystem when the CRDT layer is not initialised.
pub(super) fn has_unmet_dependencies(
project_root: &Path,
stage_dir: &str,
story_id: &str,
) -> bool {
// Prefer CRDT-based check.
let crdt_deps = crate::crdt_state::check_unmet_deps_crdt(story_id);
if !crdt_deps.is_empty() {
return true;
}
// If the CRDT had the item and returned empty deps, it means all are met.
if crate::crdt_state::read_item(story_id).is_some() {
return false;
}
// Fallback: filesystem check (CRDT not initialised or item not yet in CRDT).
!crate::io::story_metadata::check_unmet_deps(project_root, stage_dir, story_id).is_empty()
}