{"messages":[{"content":"You are a constitutional council ranking individual git commits for ownership allocation.\n\nCompare these two commits. Decide which contributed more lasting value to the project.\n\nJudge substance, not spectacle:\n- Prefer correct, lasting design and real bugfixes over churn, formatting, renames, or generated noise.\n- Prefer clarity and necessity over sheer line count. A small precise change can beat a large diffuse one.\n- Do not favor a side merely because its patch is longer or noisier.\n- Weight what the change does for the project, not the contributor's name.\n\nReturn ONLY a JSON object: {\"winner\": \"A\" or \"B\", \"ratio\": \"N:M\", \"explanation\": \"...\"}\nThe explanation must cite concrete differences in the patches (1-3 sentences).\n\nSide A — contributor: tommy-mor\nSide A — commit message:\n[81bd5f79] direction\n\nSide A — unified diff (full patch):\ndiff --git a/seed.tdsl b/seed.tdsl\nnew file mode 100644\nindex 0000000000000000000000000000000000000000..574342af3d509cb0f45b37db8194c27b23d56b73\n--- /dev/null\n+++ b/seed.tdsl\n@@ -0,0 +1 @@\n+open webui\n\n\nSide B — contributor: tommy-mor\nSide B — commit message:\n[81de487b] Fix zero-ratio guard in reducer to drop before registering items or pair.\n\nPreviously the early-return for zero-weight votes happened after\nensure_item and voted_pairs.insert, leaving ghost items in the index\nand the pair incorrectly marked as voted. Move the check to before\nany side effects.\n\nCo-Authored-By: Claude Sonnet 4.6 \n\nSide B — unified diff (full patch):\ndiff --git a/server/src/reducer.rs b/server/src/reducer.rs\nindex 6841d35cfc9de2389f340a22b8a45acb335e36c3..0e36979abe0f051493038ff7e652efc7f7a0ac80 100644\n--- a/server/src/reducer.rs\n+++ b/server/src/reducer.rs\n@@ -112,6 +112,10 @@ impl GroupState {\n if vote.ratio_right < 0 {\n vote.ratio_right = 0;\n }\n+ if vote.ratio_left == 0 || vote.ratio_right == 0 {\n+ // Zero on either side produces no valid edge; drop before registering items or pair.\n+ return;\n+ }\n \n let a_idx = self.ensure_item(&vote.a);\n let b_idx = self.ensure_item(&vote.b);\n@@ -121,10 +125,6 @@ impl GroupState {\n \n let w_a = vote.ratio_left as f64;\n let w_b = vote.ratio_right as f64;\n- if w_a == 0.0 || w_b == 0.0 {\n- // Zero on either side produces no valid edge; drop the vote.\n- return;\n- }\n \n self.add_edge_weight(b_idx, a_idx, w_a);\n self.add_edge_weight(a_idx, b_idx, w_b);\ndiff --git a/server/tests/basic.rs b/server/tests/basic.rs\nindex cc8c1a0d139f3722ba6ecd13dd001c65be835b67..08159f4a7f0850fd165817a4a1af4f31ced2ad76 100644\n--- a/server/tests/basic.rs\n+++ b/server/tests/basic.rs\n@@ -546,12 +546,10 @@ fn reducer_negative_ratio_clamped_to_zero() {\n delegate: Some(\"00000000-0000-0000-0000-000000000000:test:local/test\".to_string()),\n thread_tag: \"t\".to_string(),\n });\n- // Items are registered, but the zero-clamped vote produces no edges.\n- assert_eq!(group.idx_to_item.len(), 2);\n- let a_idx = group.item_to_idx[&item_id(\"https://slug.social/~/t/a\")];\n- let b_idx = group.item_to_idx[&item_id(\"https://slug.social/~/t/b\")];\n- assert!(!group.edges.contains_key(&(a_idx, b_idx)));\n- assert!(!group.edges.contains_key(&(b_idx, a_idx)));\n+ // Nothing registered: zero-clamped vote is dropped before ensure_item.\n+ assert!(group.idx_to_item.is_empty());\n+ assert!(group.edges.is_empty());\n+ assert!(group.voted_pairs.is_empty());\n }\n \n \n","role":"user"}],"model":"openai/gpt-chat-latest"}