fix: has_content_conflict_failure reads wrong CRDT key — auto-spawn mergemaster never fires
The function was calling `read_content(story_id)`, which returns the
story's *description* text (e.g. "Bug: Coder exits code 0 with
uncommitted work — force a commit-only respawn..."). It then scanned
that for "Merge conflict" / "CONFLICT (content):", which obviously
never matched, so the auto-spawn-mergemaster-on-content-conflict guard
in `pool/auto_assign/merge.rs` always saw `false` and skipped.
The actual gate output (where the merge runner stores the failure
message including conflict markers) lives at
`format!("{story_id}:gate_output")` — that's the key
`pipeline/advance/mod.rs:207` writes to. Read from there instead.
Witnessed: 954's merge hit a real `CONFLICT (content)` in
tests_regression.rs at 08:57:40, no mergemaster spawned, story stayed
in MergeFailure.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -72,9 +72,11 @@ pub(super) fn has_content_conflict_failure(
|
||||
if !is_merge_failure {
|
||||
return false;
|
||||
}
|
||||
// The projection does not carry the reason string; read the raw content
|
||||
// from the CRDT content store and scan for conflict markers.
|
||||
crate::db::read_content(story_id)
|
||||
// The projection does not carry the reason string; read the gate output
|
||||
// (where the merge runner persists the failure message) and scan for
|
||||
// conflict markers. NB: the key is `{story_id}:gate_output`, not `{story_id}`
|
||||
// — the latter is the story's *description* text and would never match.
|
||||
crate::db::read_content(&format!("{story_id}:gate_output"))
|
||||
.map(|content| {
|
||||
content.contains("Merge conflict") || content.contains("CONFLICT (content):")
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user