Side A fixes a real functional bug (pinned posts polluting imports) with a targeted code change plus a test verifying both stickied and pinned fields are handled. Side B is a config simplification for test discovery that reduces maintenance friction but carries risk (auto-discovery could unintentionally pick up unwanted namespaces) and has no functional/test-of-behavior impact on the product itself.
constitution · epochs · watch · epoch 3
c_bc8c17a00ed7 (tommy-mor) vs c_28dfd8015c8a (tommy-mor)
download prompt · raw event · cmp_01a7dd7bdcc92c
council reasoning
A adds lasting product behavior: skip stickied/pinned Reddit listing children via a small helper, with a unit test covering both flag shapes. B only collapses hand-enumerated kaocha suites into one ns-pattern in tests.edn—useful DX, but config hygiene rather than app correctness.
Side A changes runtime behavior by filtering stickied/pinned Reddit posts during subreddit import, adds a dedicated helper, and includes a regression test verifying only normal posts are imported. Side B improves test configuration by replacing manually enumerated Kaocha suites with automatic namespace discovery, reducing maintenance, but it does not change application behavior.
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"
+ );
+ }
}
B — c_28dfd8015c8a (tommy-mor)
message
[0bebe819] Unify kaocha test discovery to one auto-discovered suite. Replace the two hand-enumerated suites (:http-integration, :browser) with a single :all suite that picks up every test.* namespace under test/. New test files now run automatically without touching tests.edn — needed for the test.ranking namespace added alongside the #146 fix, and for any future tests. Both ./TEST.sh and CI (.github/workflows/ci.yml) invoke `clojure -M:kaocha`, so both pick up the new suite without changes. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
diff preview
diff --git a/tests.edn b/tests.edn
index 5e2b0433a66c51806d08ef38d691259cfccd1fe0..e51ffcc81eeae6f41c85d1bfc5ba32f592cc5818 100644
--- a/tests.edn
+++ b/tests.edn
@@ -1,30 +1,14 @@
#kaocha/v1
-{:tests
- [{:id :http-integration
- :test-paths ["test"]
- :source-paths ["."]
- :ns-patterns ["^test\\.integration$"
- "^test\\.auth$"
- "^test\\.grants$"
- "^test\\.invites$"
- "^test\\.room-list$"]
- :kaocha.filter/skip-meta [:skip]
- :parallel? false}
- {:id :browser
- :test-paths ["test"]
- :source-paths ["."]
- :ns-patterns ["^test\\.browser-sse$"
- "^test\\.browser-ui-morph$"
- "^test\\.browser-post-redact$"
- "^test\\.browser-room-delete$"
- "^test\\.browser-public-garden$"
- "^test\\.browser-redact-thread-index$"
- "^test\\.browser-garden-pin$"
- "^test\\.browser-vote-compare$"
- "^test\\.browser-github-resolver$"]
- :kaocha.filter/skip-meta [:skip]
- :parallel? false}]
- :plugins [:kaocha.plugin/junit-xml]
- :kaocha.plugin.junit-xml/target-file "target/kaocha-junit.xml"
- :kaocha.plugin.junit-xml/add-location-metadata? true
- :reporter kaocha.report.progress/report}
+ {:tests
+ [{:id :all
+ :test-paths ["test"]
+ :source-paths ["."]
+ ;; Pick up every test.* namespace under test/. New files don't need to be
+ ;; enumerated here — drop them in test/ with `(ns test.foo …)` and they run.
+ :ns-patterns ["^test\\..+"]
+ :kaocha.filter/skip-meta [:skip]
+ :parallel? false}]
+ :plugins [:kaocha.plugin/junit-xml]
+ :kaocha.plugin.junit-xml/target-file "target/kaocha-junit.xml"
+ :kaocha.plugin.junit-xml/add-location-metadata? true
+ :reporter kaocha.report.progress/report}
Hardlinks — judgments / attempts / prompt
judgments
attempts
Prompt text is loaded only by the download route.