Side B is a real bugfix that prevents ghost items and incorrectly marked voted pairs by reordering a guard clause before side effects, with an updated test verifying the corrected behavior. Side A merely adds a trivial one-line seed file with no functional code change or lasting value.
constitution · epochs · watch · epoch 3
c_d2fd40385778 (tommy-mor) vs c_abd68b5e771a (tommy-mor)
download prompt · raw event · cmp_b208bac771f1e8
council reasoning
B fixes a real correctness bug by moving the zero-ratio early-return before ensure_item/voted_pairs side effects, and updates tests accordingly. A only adds a one-line seed file with negligible lasting design or functional value.
Side B fixes a real correctness bug by moving the zero-ratio guard before `ensure_item` and `voted_pairs.insert`, preventing ghost items and incorrectly recorded voted pairs. It also updates the test to verify that no items, edges, or voted pairs are registered for zero-weight votes, whereas Side A only adds a new file containing the single line `open webui` without implementing project functionality.
sides
A — c_d2fd40385778 (tommy-mor)
message
[81bd5f79] direction
diff preview
diff --git a/seed.tdsl b/seed.tdsl new file mode 100644 index 0000000000000000000000000000000000000000..574342af3d509cb0f45b37db8194c27b23d56b73 --- /dev/null +++ b/seed.tdsl @@ -0,0 +1 @@ +open webui
B — c_abd68b5e771a (tommy-mor)
message
[81de487b] Fix zero-ratio guard in reducer to drop before registering items or pair. Previously the early-return for zero-weight votes happened after ensure_item and voted_pairs.insert, leaving ghost items in the index and the pair incorrectly marked as voted. Move the check to before any side effects. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
diff preview
diff --git a/server/src/reducer.rs b/server/src/reducer.rs
index 6841d35cfc9de2389f340a22b8a45acb335e36c3..0e36979abe0f051493038ff7e652efc7f7a0ac80 100644
--- a/server/src/reducer.rs
+++ b/server/src/reducer.rs
@@ -112,6 +112,10 @@ impl GroupState {
if vote.ratio_right < 0 {
vote.ratio_right = 0;
}
+ if vote.ratio_left == 0 || vote.ratio_right == 0 {
+ // Zero on either side produces no valid edge; drop before registering items or pair.
+ return;
+ }
let a_idx = self.ensure_item(&vote.a);
let b_idx = self.ensure_item(&vote.b);
@@ -121,10 +125,6 @@ impl GroupState {
let w_a = vote.ratio_left as f64;
let w_b = vote.ratio_right as f64;
- if w_a == 0.0 || w_b == 0.0 {
- // Zero on either side produces no valid edge; drop the vote.
- return;
- }
self.add_edge_weight(b_idx, a_idx, w_a);
self.add_edge_weight(a_idx, b_idx, w_b);
diff --git a/server/tests/basic.rs b/server/tests/basic.rs
index cc8c1a0d139f3722ba6ecd13dd001c65be835b67..08159f4a7f0850fd165817a4a1af4f31ced2ad76 100644
--- a/server/tests/basic.rs
+++ b/server/tests/basic.rs
@@ -546,12 +546,10 @@ fn reducer_negative_ratio_clamped_to_zero() {
delegate: Some("00000000-0000-0000-0000-000000000000:test:local/test".to_string()),
thread_tag: "t".to_string(),
});
- // Items are registered, but the zero-clamped vote produces no edges.
- assert_eq!(group.idx_to_item.len(), 2);
- let a_idx = group.item_to_idx[&item_id("https://slug.social/~/t/a")];
- let b_idx = group.item_to_idx[&item_id("https://slug.social/~/t/b")];
- assert!(!group.edges.contains_key(&(a_idx, b_idx)));
- assert!(!group.edges.contains_key(&(b_idx, a_idx)));
+ // Nothing registered: zero-clamped vote is dropped before ensure_item.
+ assert!(group.idx_to_item.is_empty());
+ assert!(group.edges.is_empty());
+ assert!(group.voted_pairs.is_empty());
}
Hardlinks — judgments / attempts / prompt
judgments
attempts
Prompt text is loaded only by the download route.