constitution · epochs · watch · epoch 3

comparison

c_b7cc67300477 (tommy-mor) vs c_cf0a514b261a (tommy-mor)

download prompt · raw event · cmp_dcf82721e591d0

council reasoning

~anthropic/claude-sonnet-latest · winner B · 6:4 · permalink

B removes genuinely dead/redundant code and correctly updates the test to reflect actual reducer behavior, providing a small but real simplification and behavioral clarification. A merely adds a randomized (non-seeded) test that risks flakiness and mainly demonstrates existing functionality rather than fixing or clarifying behavior.

~x-ai/grok-latest · winner A · 2:1 · permalink

A adds a non-trivial property test that the core rank-centrality path recovers true order from a minimal spanning-tree of perfect-ratio votes, locking in lasting algorithmic behavior. B only deletes a dead zero-ratio early-return and retunes an existing test to the already-enforced contract, which is useful hygiene but much smaller enduring impact.

sides

A — c_b7cc67300477 (tommy-mor)

message

[9e3d989b] Add test that 25 spanning-tree votes with perfect ratios sort the alphabet.

Demonstrates rank centrality recovers the true order from a random connected
comparison graph when each vote encodes item strength as (idx+1).

Co-authored-by: Cursor <cursoragent@cursor.com>

diff preview

diff --git a/server/src/ranking.rs b/server/src/ranking.rs
index c9b4d5d89d2f22cf53a5b43eb979e19a11bc89a1..93cb4c9f5887a1e598cdc9d648751055f618adcc 100644
--- a/server/src/ranking.rs
+++ b/server/src/ranking.rs
@@ -369,6 +369,48 @@ mod tests {
         assert_eq!(comp1, vec!["c", "d"]);
     }
 
+    /// A random spanning tree over 26 items needs only n−1 = 25 pairwise votes.
+    /// When each vote uses the "perfect" ratio (strength left : strength right =
+    /// (idx_left+1) : (idx_right+1)), rank centrality recovers the true order.
+    /// See `rank-eric.py` (Eric's demo of Negahban–Oh–Shah rank centrality).
+    #[test]
+    fn twenty_five_random_votes_perfect_ratios_sort_alphabet() {
+        use rand::seq::SliceRandom;
+
+        const N: usize = 26;
+        let letters: Vec<char> = (0..N).map(|i| char::from(b'a' + i as u8)).collect();
+
+        let mut rng = rand::thread_rng();
+        let mut perm: Vec<usize> = (0..N).collect();
+        perm.shuffle(&mut rng);
+
+        let mut g = mk_group();
+        for k in 1..N {
+            let i = *perm[..k].choose(&mut rng).unwrap();
+            let j = perm[k];
+            let (a, b) = (letters[i], letters[j]);
+            g.apply_vote(vote(
+                k as i64,
+                &a.to_string(),
+                &b.to_string(),
+                (i + 1) as i32,
+                (j + 1) as i32,
+            ));
+        }
+
+        let ranked = ranked_items(&g);
+        assert_eq!(ranked.len(), N);
+        for (rank, item) in ranked.iter().enumerate() {
+            let expected = char::from(b'a' + (N - 1 - rank) as u8);
+            assert_eq!(
+                item.item.as_str(),
+                expected.to_string(),
+                "rank {rank}: expected '{expected}', got '{}'",
+                item.item.as_str()
+            );
+        }
+    }
+
     #[test]
     fn subset_ranking_ranks_within_component_only() {
         let mut g = mk_group();

download full diff A

B — c_cf0a514b261a (tommy-mor)

message

[047b82bd] Remove redundant zero-ratio guard from reducer.

Zeros are already rejected at the DSL parser and browser handler;
the guard in apply_vote was dead code. The negative clamping stays
since add_edge_weight already skips weight-0 edges correctly.

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 0e36979abe0f051493038ff7e652efc7f7a0ac80..efbf7f67ff24c7a2989102fe62879b2794a27c5f 100644
--- a/server/src/reducer.rs
+++ b/server/src/reducer.rs
@@ -112,11 +112,6 @@ 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);
 
diff --git a/server/tests/basic.rs b/server/tests/basic.rs
index 08159f4a7f0850fd165817a4a1af4f31ced2ad76..1748769ccf7196b2d81cf556d5368c7e723f6a4e 100644
--- a/server/tests/basic.rs
+++ b/server/tests/basic.rs
@@ -533,7 +533,7 @@ fn dsl_parse_rejects_zero_zero_vote_ratio() {
 #[test]
 fn reducer_negative_ratio_clamped_to_zero() {
     let _state = ReducerState::default();
-    // GroupState::apply_vote clamps negatives to 0; when either side is 0 the vote is dropped.
+    // apply_vote clamps negatives to 0; add_edge_weight skips zero-weight edges.
     let mut group = GroupState::new();
     group.apply_vote(slugsocial_server::reducer::VoteData {
         ts: 1,
@@ -546,10 +546,9 @@ fn reducer_negative_ratio_clamped_to_zero() {
         delegate: Some("00000000-0000-0000-0000-000000000000:test:local/test".to_string()),
         thread_tag: "t".to_string(),
     });
-    // Nothing registered: zero-clamped vote is dropped before ensure_item.
-    assert!(group.idx_to_item.is_empty());
+    // Items and pair are registered; edges are absent because weight 0 is skipped.
+    assert_eq!(group.idx_to_item.len(), 2);
     assert!(group.edges.is_empty());
-    assert!(group.voted_pairs.is_empty());
 }
 
 

download full diff B

Hardlinks — judgments / attempts / prompt

prompt download

judgments

attempts

Prompt text is loaded only by the download route.