fix(901): unblock_story works on CRDT-only stories post-865
Bug 901: `unblock_story` (and the chat `unblock` command) routed through
`parse_front_matter` and errored with "Missing front matter" on any
post-865 story (story content is now CRDT-only with no YAML on disk).
In `chat/commands/unblock.rs::unblock_by_story_id`:
- Drop the early `parse_front_matter` gate.
- Read story name and blocked state from the CRDT register API instead
of parsed YAML (`crdt_state::read_item`, `pipeline_state::read_typed`).
- Keep the legacy fallback cleanup, but gate it on the content actually
starting with a `---` YAML block, so CRDT-only stories don't hit a
parse error there either.
- Remove the now-unused `parse_front_matter` import.
Surfaced a second sub-bug: even when the state-machine transition
fired (`Blocked + Unblock → Coding`), the CRDT `blocked` register was
never explicitly cleared. Pre-865 the YAML-strip content_transform
cleared it as a side effect; post-865 there is no YAML to strip.
- Add `crdt_state::set_blocked(story_id, bool)` parallel to
`set_retry_count`. Wired through `crdt_state::write` and the
crate-level re-export.
- `agents::lifecycle::transition_to_unblocked` now calls
`set_blocked(story_id, false)` alongside `set_retry_count(0)` so
the legacy register stays in sync with the typed stage.
Test: `unblock_command_works_on_crdt_only_story_no_yaml` seeds a CRDT
entry with no YAML on disk, runs unblock, asserts success + cleared
blocked + retry_count=0. All 10 existing unblock tests still pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -53,7 +53,8 @@ pub use types::{
|
||||
};
|
||||
pub use write::{
|
||||
bump_retry_count, migrate_names_from_slugs, migrate_story_ids_to_numeric, name_from_story_id,
|
||||
set_agent, set_depends_on, set_mergemaster_attempted, set_qa_mode, set_retry_count, write_item,
|
||||
set_agent, set_blocked, set_depends_on, set_mergemaster_attempted, set_qa_mode,
|
||||
set_retry_count, write_item,
|
||||
};
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -285,6 +285,25 @@ pub fn set_retry_count(story_id: &str, count: i64) {
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the `blocked` register on a story to the given value.
|
||||
///
|
||||
/// Pure metadata operation — the item's stage is not changed.
|
||||
/// Use this alongside a state-machine transition out of `Blocked` /
|
||||
/// `MergeFailure` to keep the legacy `blocked` register in sync with the
|
||||
/// typed stage post-865 (where YAML side-effects no longer clear the
|
||||
/// register on their own).
|
||||
pub fn set_blocked(story_id: &str, blocked: bool) {
|
||||
let Some(state_mutex) = get_crdt() else {
|
||||
return;
|
||||
};
|
||||
let Ok(mut state) = state_mutex.lock() else {
|
||||
return;
|
||||
};
|
||||
if let Some(&idx) = state.index.get(story_id) {
|
||||
apply_and_persist(&mut state, |s| s.crdt.doc.items[idx].blocked.set(blocked));
|
||||
}
|
||||
}
|
||||
|
||||
/// Increment `retry_count` by 1 and return the new value.
|
||||
///
|
||||
/// Pure metadata operation — the item's stage is not changed.
|
||||
|
||||
@@ -10,7 +10,7 @@ mod migrations;
|
||||
mod tests;
|
||||
|
||||
pub use item::{
|
||||
bump_retry_count, set_agent, set_depends_on, set_mergemaster_attempted, set_qa_mode,
|
||||
set_retry_count, write_item,
|
||||
bump_retry_count, set_agent, set_blocked, set_depends_on, set_mergemaster_attempted,
|
||||
set_qa_mode, set_retry_count, write_item,
|
||||
};
|
||||
pub use migrations::{migrate_names_from_slugs, migrate_story_ids_to_numeric, name_from_story_id};
|
||||
|
||||
Reference in New Issue
Block a user