constitution · epochs · watch · epoch 3

comparison

c_bc8c17a00ed7 (tommy-mor) vs c_cf0a514b261a (tommy-mor)

download prompt · raw event · cmp_36d06fbae98ceb

council reasoning

openai/gpt-chat-latest · winner A · 4:1 · permalink

Side A fixes importer behavior by explicitly skipping stickied/pinned Reddit posts in `parse_children`, adds a dedicated `child_is_pinned` helper checking both `stickied` and `pinned` flags, and includes a regression test covering both cases. Side B mainly removes a guard that is asserted to be unreachable because earlier validation already rejects zero ratios, updating tests to reflect existing behavior rather than adding new functionality or fixing a user-visible issue.

openai/gpt-5.3-chat · winner A · 3:1 · permalink

A adds a concrete behavioral improvement by filtering out stickied/pinned Reddit posts in `parse_children`, with a dedicated helper and test ensuring only real posts are imported. B mainly removes a supposedly dead zero-ratio guard in `apply_vote` and adjusts tests, which is a cleanup with minor semantic change but less clear user-facing impact.

openai/gpt-5.2-chat · winner A · 3:1 · permalink

Side A adds a concrete behavioral improvement by skipping stickied/pinned Reddit posts during import via a new `child_is_pinned` check in `parse_children`, along with a focused test verifying only non-pinned posts are returned. Side B merely removes a zero-ratio early return in `apply_vote` and adjusts a test, changing when items are registered but not adding new functionality; it’s largely cleanup of redundant logic.

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

Side A fixes a real behavioral bug (pinned posts polluting subreddit imports) with a working implementation and a dedicated regression test, directly improving data correctness. Side B is a minor cleanup removing dead code and relies on assuming add_edge_weight's zero-skip behavior is correct elsewhere, which is lower-risk but also lower-impact than A's functional fix.

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

A adds lasting import behavior by filtering stickied/pinned Reddit posts in parse_children, with a dedicated helper and a focused unit test covering both sticky fields and a normal post. B only deletes a defensive zero-ratio early-return already enforced upstream and adjusts a test to match; useful hygiene, but no new capability or user-facing fix.

sides

A — c_bc8c17a00ed7 (tommy-mor)

message

[03cd8f2e] Skip pinned Reddit posts when importing subreddit listings.

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

diff preview

diff --git a/server/src/reddit.rs b/server/src/reddit.rs
index f409764c1e1f36216f1b08107043c2eab905694c..fa5577f8ee0a8c53ff4dbec988a90a5d2fc3cdee 100644
--- a/server/src/reddit.rs
+++ b/server/src/reddit.rs
@@ -661,6 +661,7 @@ pub fn map_children_url(id: &ItemId, api_base: &str) -> String {
 /// Parse a subreddit listing payload into `(child_id, child_payload)` entries.
 /// Each child id is the post's permalink under `reddit.com/…`, and the payload
 /// is the raw `{kind, data}` listing element (persisted per child).
+/// Pinned / stickied posts are skipped.
 fn parse_children(_parent: &ItemId, payload: &Value) -> Vec<(ItemId, Value)> {
     let mut out = Vec::new();
     let children = match payload.pointer("/data/children").and_then(|c| c.as_array()) {
@@ -668,6 +669,9 @@ fn parse_children(_parent: &ItemId, payload: &Value) -> Vec<(ItemId, Value)> {
         None => return out,
     };
     for child in children {
+        if child_is_pinned(child) {
+            continue;
+        }
         let permalink = match child.pointer("/data/permalink").and_then(|p| p.as_str()) {
             Some(p) if !p.is_empty() => p,
             _ => continue,
@@ -680,6 +684,15 @@ fn parse_children(_parent: &ItemId, payload: &Value) -> Vec<(ItemId, Value)> {
     out
 }
 
+fn child_is_pinned(child: &Value) -> bool {
+    let data = match child.get("data") {
+        Some(d) => d,
+        None => return false,
+    };
+    data.get("stickied").and_then(|v| v.as_bool()) == Some(true)
+        || data.get("pinned").and_then(|v| v.as_bool()) == Some(true)
+}
+
 fn parse_reddit_view(id: &ItemId, v: &Value) -> Option<crate::reducer::EntityData> {
     let segments: Vec<&str> = id.as_str().split('/').collect();
 
@@ -853,4 +866,46 @@ mod tests {
             Some("http://v3.redgifs.com/watch/impossibleprestigioushedgehog")
         );
     }
+
+    #[test]
+    fn parse_children_skips_pinned_posts() {
+        let payload = serde_json::json!({
+            "kind": "Listing",
+            "data": {
+                "children": [
+                    {
+                        "kind": "t3",
+                        "data": {
+                            "title": "Official rules (pinned)",
+                            "permalink": "/r/rust/comments/pin/official_rules/",
+                            "stickied": true
+                        }
+                    },
+                    {
+                        "kind": "t3",
+                        "data": {
+                            "title": "Also pinned via pinned field",
+                            "permalink": "/r/rust/comments/pin2/also_pinned/",
+                            "pinned": true
+                        }
+                    },
+                    {
+                        "kind": "t3",
+                        "data": {
+                            "title": "Normal post",
+                            "permalink": "/r/rust/comments/aaa/normal_post/",
+                            "stickied": false
+                        }
+                    }
+                ]
+            }
+        });
+        let parent = ItemId::from_url("https://reddit.com/r/rust").unwrap();
+        let children = parse_children(&parent, &payload);
+        assert_eq!(children.len(), 1);
+        assert_eq!(
+            children[0].0.as_str(),
+            "https://reddit.com/r/rust/comments/aaa"
+        );
+    }
 }

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.