wip(929): stage 1 — migrate chat/commands/* off yaml_legacy
Each chat command that previously read parse_front_matter for story metadata (name, agent, depends_on, blocked, retry_count, merge_failure, qa_mode) now reads from the typed CRDT API: - WorkItem (via crdt_state::read_item) for pipeline-item registers. - MergeJobView (via crdt_state::read_merge_job) for the merge failure detail text, which has its own LWW-map CRDT entry. Files migrated: depends.rs, freeze.rs, move_story.rs, overview.rs, status/render.rs, triage.rs, unblock.rs, unreleased.rs. unblock.rs: also removes the legacy front-matter cleanup branch that fired when the typed Blocked→Coding transition failed. Post-929 there is no YAML on disk to clean; the fallback now just resets retry_count in the CRDT. triage.rs: drops the YAML-only `review_hold` and `coverage_baseline` fields from the dump. These have no CRDT register and were never load-bearing on the triage output; if needed later, add a CRDT register and surface it back. Tests: - The three status/render merge-failure rendering tests now seed a MergeJob CRDT entry via write_merge_job instead of writing YAML. - The unblock test that asserted YAML cleanup on disk is now an assertion on the CRDT registers (blocked=false, retry_count=0). Also re-seeded in `2_blocked` stage so the typed Blocked → Coding transition actually fires (not the fallback path). All 2855 tests pass; fmt clean; clippy clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -140,55 +140,13 @@ fn slug_to_name(slug: &str) -> String {
|
||||
words.join(" ")
|
||||
}
|
||||
|
||||
/// Find the human-readable name of a story by searching content store then filesystem.
|
||||
fn find_story_name(root: &std::path::Path, num_str: &str) -> Option<String> {
|
||||
// Try content store first.
|
||||
for id in crate::db::all_content_ids() {
|
||||
let file_num = id.split('_').next().unwrap_or("");
|
||||
if file_num == num_str
|
||||
&& let Some(c) = crate::db::read_content(&id)
|
||||
{
|
||||
return crate::db::yaml_legacy::parse_front_matter(&c)
|
||||
.ok()
|
||||
.and_then(|m| m.name);
|
||||
}
|
||||
}
|
||||
|
||||
// Fallback: filesystem scan.
|
||||
const STAGES: &[&str] = &[
|
||||
"1_backlog",
|
||||
"2_current",
|
||||
"3_qa",
|
||||
"4_merge",
|
||||
"5_done",
|
||||
"6_archived",
|
||||
];
|
||||
for stage in STAGES {
|
||||
let dir = root.join(".huskies").join("work").join(stage);
|
||||
if !dir.exists() {
|
||||
continue;
|
||||
}
|
||||
if let Ok(entries) = std::fs::read_dir(&dir) {
|
||||
for entry in entries.flatten() {
|
||||
let path = entry.path();
|
||||
if path.extension().and_then(|e| e.to_str()) != Some("md") {
|
||||
continue;
|
||||
}
|
||||
if let Some(stem) = path.file_stem().and_then(|s| s.to_str()) {
|
||||
let file_num = stem
|
||||
.split('_')
|
||||
.next()
|
||||
.filter(|s| !s.is_empty() && s.chars().all(|c| c.is_ascii_digit()))
|
||||
.unwrap_or("");
|
||||
if file_num == num_str {
|
||||
return std::fs::read_to_string(&path).ok().and_then(|c| {
|
||||
crate::db::yaml_legacy::parse_front_matter(&c)
|
||||
.ok()
|
||||
.and_then(|m| m.name)
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
/// Find the human-readable name of a story from the CRDT (story 929 —
|
||||
/// CRDT is the sole source of story metadata).
|
||||
fn find_story_name(_root: &std::path::Path, num_str: &str) -> Option<String> {
|
||||
let items = crate::crdt_state::read_all_items()?;
|
||||
for item in items {
|
||||
if item.story_id().split('_').next().unwrap_or("") == num_str {
|
||||
return item.name().map(str::to_string);
|
||||
}
|
||||
}
|
||||
None
|
||||
|
||||
Reference in New Issue
Block a user