You are a constitutional council ranking individual git commits for ownership allocation. Compare these two commits. Decide which contributed more lasting value to the project. Judge substance, not spectacle: - Prefer correct, lasting design and real bugfixes over churn, formatting, renames, or generated noise. - Prefer clarity and necessity over sheer line count. A small precise change can beat a large diffuse one. - Do not favor a side merely because its patch is longer or noisier. - Weight what the change does for the project, not the contributor's name. Return ONLY a JSON object: {"winner": "A" or "B", "ratio": "N:M", "explanation": "..."} The explanation must cite concrete differences in the patches (1-3 sentences). Side A — contributor: tommy-mor Side A — commit message: [10c9caac] Fix all workspace clippy warnings. Wire up a missing ui_action test, allow dead code in shared integration helpers, and apply small clippy cleanups across server and types. Co-authored-by: Cursor Side A — unified diff (full patch): diff --git a/server/src/dsl.rs b/server/src/dsl.rs index a45c5b33e10d0d2ea48c7313061cfa1e6430bcfc..faa8aac6616bc6ea2b102d08ae999c01a716ef6e 100644 --- a/server/src/dsl.rs +++ b/server/src/dsl.rs @@ -927,9 +927,7 @@ mod tests { #[test] fn parse_vote_rejects_zero_zero_ratio() { let err = parse_full("{tie placeholder}\n~/a 0:0 ~/b").unwrap_err(); - let msg = match err { - DslError::Parse(m) => m, - }; + let DslError::Parse(msg) = err; assert!( msg.contains("0:0"), "expected 0:0 rejection message, got: {msg}" diff --git a/server/src/html/garden/tests.rs b/server/src/html/garden/tests.rs index c2036fca7752aef63d260e36cfe9649f63b5c550..0a1be1290fdc93197ca191197a473840bb4decbc 100644 --- a/server/src/html/garden/tests.rs +++ b/server/src/html/garden/tests.rs @@ -346,7 +346,7 @@ fn vote_compare_item_card_renders_github_import_markup() { "headline": "#1 Compare card", "sublines": ["State: open"], }); - let body = format!("```slug-github-card\n{}\n```", json.to_string()); + let body = format!("```slug-github-card\n{json}\n```"); let html = vote_compare_item_card( &nav, &item, diff --git a/server/src/html/ui_action.rs b/server/src/html/ui_action.rs index 2589a2cc00bb7b18cd19ebcbb938083122d6921d..5e4131dd346a6f80bfe091a9b0cf7902721bc47f 100644 --- a/server/src/html/ui_action.rs +++ b/server/src/html/ui_action.rs @@ -246,6 +246,7 @@ mod tests { ); } + #[test] fn set_new_thread_compose_expanded_true() { let template = serde_json::json!({ "action": "set_new_thread_compose_expanded", diff --git a/server/src/offline.rs b/server/src/offline.rs index 2db6f67e22e00a24ce673d13095644dd9fa9342d..93d4d5ee55449da644f732bc0ba007ee4c2c7079 100644 --- a/server/src/offline.rs +++ b/server/src/offline.rs @@ -167,7 +167,7 @@ fn rankings_for_simulated( .iter() .map(|parent| { let scoped_content = simulated - .content_for_scope(&scope) + .content_for_scope(scope) .unwrap_or_else(|| simulated.public()); let scoped = build_children_rankings(scoped_content, parent); let components: Vec = scoped @@ -254,7 +254,9 @@ fn ingest_parse_error(raw: &str) -> Option { dsl::parse_full(raw).err().map(|e| e.to_string()) } -fn load_events_from_jsonl(path: &Path) -> Result<(usize, Vec<(usize, Event)>, Vec), std::io::Error> { +type JsonlEventsLoad = Result<(usize, Vec<(usize, Event)>, Vec), std::io::Error>; + +fn load_events_from_jsonl(path: &Path) -> JsonlEventsLoad { let text = std::fs::read_to_string(path)?; let total_lines = text.lines().count(); let mut events = Vec::new(); diff --git a/server/src/resolvers/github.rs b/server/src/resolvers/github.rs index 30dd4cdac96de0e3da4fa03fdf82f91bed73bfe0..3cec5e8b7249a4597c378890cc9e6125104e76c3 100644 --- a/server/src/resolvers/github.rs +++ b/server/src/resolvers/github.rs @@ -749,6 +749,6 @@ mod tests { GithubImportKind::Issue, ); assert!(card.sublines.iter().any(|l| l.contains("@octo"))); - assert_eq!(card.excerpt.as_deref(), Some("The issue body.").as_deref()); + assert_eq!(card.excerpt.as_deref(), Some("The issue body.")); } } diff --git a/server/tests/basic.rs b/server/tests/basic.rs index 31a35251a8abd6f4a48c1d7782b6985f621375e1..9d83e7a97e2c7494790db17c4b5b30c181705026 100644 --- a/server/tests/basic.rs +++ b/server/tests/basic.rs @@ -337,7 +337,7 @@ async fn event_log_handles_corrupt_lines() { .unwrap(); // Add empty line. - writeln!(f, "").unwrap(); + writeln!(f).unwrap(); let (loaded, bad) = log.load_all().await.unwrap(); assert_eq!(loaded.len(), 2); @@ -511,9 +511,7 @@ fn dsl_parse_rejects_zero_zero_vote_ratio() { "~/t/a {a}\n~/t/b {b}\n{zero}\n~/t/a 0:0 ~/t/b\n", ) .expect_err("0:0 vote must be rejected by the parser"); - let msg = match err { - slugsocial_server::dsl::DslError::Parse(m) => m, - }; + let slugsocial_server::dsl::DslError::Parse(msg) = err; assert!( msg.contains("0:0"), "expected message about invalid 0:0 ratio, got: {msg}" @@ -904,7 +902,7 @@ fn posts_by_actor_indexes_and_profile_visibility() { fn feed_query(state: &ReducerState, cutoff: i64, limit: usize) -> (usize, Vec) { let matching: Vec<&str> = state.ingests_ordered.iter().rev() .map(|id| id.as_str()) - .take_while(|id| state.ingests_by_id.get(*id).map_or(false, |ing| ing.ts > cutoff)) + .take_while(|id| state.ingests_by_id.get(*id).is_some_and(|ing| ing.ts > cutoff)) .filter(|id| { state.ingests_by_id.get(*id).is_some_and(|ing| { let scope = slugsocial_server::reducer::scope_from_room_wire(&ing.room_id); diff --git a/server/tests/integration_health.rs b/server/tests/integration_health.rs index 481222d8c48c44fcfb7e9ba26cf7644b5c26d5f4..351aae6b0e9738021886a076ee08fab5cf5a0001 100644 --- a/server/tests/integration_health.rs +++ b/server/tests/integration_health.rs @@ -7,7 +7,7 @@ async fn test_healthz() { let (addr, _tmp, _log, _handle) = create_test_server().await; let client = reqwest::Client::new(); let response = client - .get(&format!("http://{}/healthz", addr)) + .get(format!("http://{}/healthz", addr)) .send() .await .unwrap(); diff --git a/server/tests/integration_rpc.rs b/server/tests/integration_rpc.rs index ccd89a02594bd2a8e7047edafca04b0e54384139..ec446d94a38c8d6961d2135dd031da7ab2a39b48 100644 --- a/server/tests/integration_rpc.rs +++ b/server/tests/integration_rpc.rs @@ -440,7 +440,6 @@ async fn test_rank_history() { let bearer = test_bearer(); let ingest = |delegate: &str, text: &str| { let client = client.clone(); - let addr = addr; let bearer = bearer.clone(); let text = text.to_string(); let delegate = delegate.to_string(); diff --git a/server/tests/support/mod.rs b/server/tests/support/mod.rs index 84dc1d68b6c1e1fdfdbd0757139c06c3daf1e9a6..4a620eaa875e7a1145f2a4e82cc4ff2be21d5345 100644 --- a/server/tests/support/mod.rs +++ b/server/tests/support/mod.rs @@ -1,3 +1,6 @@ +//! Shared helpers for integration tests; each test binary uses a different subset. +#![allow(dead_code)] + use sha2::{Digest, Sha256}; use slugsocial_server::{ event_log::EventLog, diff --git a/types/src/paths.rs b/types/src/paths.rs index ebc299c5e1af456c3e4b7fa45ed9fb23313e88c4..d2e799942b98dd7342764475deb17903fb60c600 100644 --- a/types/src/paths.rs +++ b/types/src/paths.rs @@ -411,7 +411,7 @@ mod tests { #[test] fn garden_item_url_deref_to_str() { let g = GardenItemUrl::from_storage_str("https://slug.social/~/x", "public"); - let s: &str = &*g; + let s: &str = &g; assert_eq!(s, "https://slug.social/~/x"); } Side B — contributor: tommy-mor Side B — commit message: [51e73d38] voting looks better? Side B — unified diff (full patch): diff --git a/server/static/theme_default.css b/server/static/theme_default.css index 5f60ff7a8cf9045d8d43228baad8ba80ad057f2a..ec0fbe7acee0aa2802f978f14a9b0fc86e78c5b8 100644 --- a/server/static/theme_default.css +++ b/server/static/theme_default.css @@ -844,18 +844,25 @@ a.ont-vote-compare-btn { color: var(--ui); cursor: pointer; font-size: 11px; - padding: 2px 8px; + padding: 3px 10px; text-decoration: none; display: inline-flex; align-items: center; gap: 4px; font-family: inherit; + border-radius: 2px; } button.ont-pin-btn:hover, a.ont-vote-compare-btn:hover { color: var(--signal); } +button.ont-pin-btn:focus-visible, +a.ont-vote-compare-btn:focus-visible { + outline: 2px solid var(--link); + outline-offset: 2px; +} button.ont-pin-btn-active { border-color: var(--link); color: var(--signal); + background: color-mix(in srgb, var(--link) 12%, var(--g4)); } .ont-garden-child-actions { display: inline-flex; @@ -868,12 +875,33 @@ a.ont-garden-vote-ico, span.ont-garden-pinned-here { font-size: 13px; line-height: 1; - padding: 0 2px; - border: none; - background: transparent; + padding: 2px 6px; + min-width: 26px; + min-height: 26px; + box-sizing: border-box; + border: var(--bv) solid; + border-color: var(--hi) var(--lo) var(--lo) var(--hi); + border-radius: 2px; + background: var(--g3); cursor: pointer; text-decoration: none; color: inherit; + display: inline-flex; + align-items: center; + justify-content: center; +} +a.ont-garden-vote-ico:hover { + color: var(--signal); + background: var(--g4); +} +span.ont-garden-pinned-here { + border-color: var(--link); + color: var(--signal); + cursor: default; +} +button.ont-garden-pin-ico:focus-visible { + outline: 2px solid var(--link); + outline-offset: 2px; } body.view-ontology-light ol.ont-ranking-list li, body.view-ontology-light ul.ont-group-list li { @@ -889,8 +917,19 @@ body.view-ontology-light ul.ont-group-list li .item-link { /* Vote compare page */ .vote-compare-shell { - margin: 12px 0; + margin: 12px 0 20px; max-width: 720px; + padding: 14px 16px 18px; + background: var(--g2); + border: var(--bv-lg) solid; + border-color: var(--hi) var(--lo) var(--lo) var(--hi); +} +body.view-vote-compare .vote-compare-shell > h2 { + margin-top: 0; + font-size: 12px; + letter-spacing: 0.12em; + text-transform: uppercase; + color: var(--meta); } .vote-compare-pair { display: flex; @@ -899,12 +938,20 @@ body.view-ontology-light ul.ont-group-list li .item-link { gap: 10px 16px; margin: 10px 0; } +.vote-compare-item { + text-decoration: none; +} .vote-compare-item code { font-size: 13px; } +.vote-compare-item:hover code { + color: var(--signal); +} .vote-compare-vs { color: var(--meta); - font-size: 12px; + font-size: 11px; + letter-spacing: 0.1em; + text-transform: uppercase; } .vote-compare-slider-label { display: flex; @@ -917,7 +964,7 @@ body.view-ontology-light ul.ont-group-list li .item-link { #vote-preference-slider { flex: 1 1 180px; min-width: 120px; - accent-color: var(--ui); + accent-color: var(--link); } .vote-thread-picker { margin: 10px 0; @@ -931,9 +978,17 @@ body.view-ontology-light ul.ont-group-list li .item-link { } #vote-thread-select { min-width: 160px; + background: var(--g3); + border: var(--bv) solid; + border-color: var(--hi) var(--lo) var(--lo) var(--hi); + color: var(--ui); + font-size: 12px; + padding: 3px 8px; } #vote-edge-history-region { margin: 14px 0 18px; + padding-bottom: 8px; + border-bottom: 1px dashed var(--lo); } .vote-compare-preview-wrap { margin: 12px 0; @@ -946,8 +1001,37 @@ body.view-ontology-light ul.ont-group-list li .item-link { #vote-compare-preview { min-height: 48px; } +.vote-explain-label { + display: block; + font-size: 12px; + color: var(--meta); + margin: 12px 0 4px; +} +body.view-vote-compare #vote-explain { + width: 100%; + max-width: 100%; + box-sizing: border-box; + background: var(--g3); + border: var(--bv) solid; + border-color: var(--hi) var(--lo) var(--lo) var(--hi); + color: var(--prose); + font: inherit; + line-height: 1.45; + padding: 8px 10px; +} +body.view-vote-compare #vote-explain:focus { + outline: none; + border-color: var(--link); + box-shadow: 0 0 0 2px color-mix(in srgb, var(--link) 22%, transparent); +} +body.view-vote-compare #vote-compare-form button[type="submit"] { + margin-top: 6px; +} .vote-edge-history-title { - font-size: 13px; + font-size: 12px; + letter-spacing: 0.06em; + text-transform: uppercase; + color: var(--meta); margin: 16px 0 8px; } ol.vote-edge-history { @@ -968,6 +1052,8 @@ li.vote-edge-history-row { .vote-edge-bar { margin-top: 4px; max-width: 100%; + border-radius: 2px; + overflow: hidden; } .vote-edge-reason { margin-top: 4px; diff --git a/server/static/theme_retro_craft.css b/server/static/theme_retro_craft.css index 3853e9edaf4c77c62dcf350ff28920448dd943a8..092d4b3540b052cc86870179e4c264541c4446cc 100644 --- a/server/static/theme_retro_craft.css +++ b/server/static/theme_retro_craft.css @@ -587,3 +587,337 @@ body.view-ontology #controls { padding-right: 1.25rem; } } + +/* ---------------------------------------------------------------- + Ontology garden: pin HUD, row pins, vote-compare + (Global craft `code` + `button[type=submit]` are tuned for dark + thread pages; these overrides match the cream ontology shell.) + ---------------------------------------------------------------- */ +body.view-ontology #slug-pin-hud.slug-pin-hud { + margin-left: auto; + max-width: min(42vw, 280px); + font-family: var(--font-ui); + font-size: 0.72rem; + color: #5c574e; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +body.view-ontology .slug-pin-hud-link { + color: #1a4a8c; + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 0.25rem; +} +body.view-ontology .slug-pin-hud-link:hover { + color: #0d3d82; + text-decoration: underline; +} +body.view-ontology .slug-pin-hud-glyph { + font-size: 0.95rem; + line-height: 1; +} + +body.view-ontology .ont-item-meta { + flex-wrap: wrap; + align-items: center; + gap: 0.35rem; +} +body.view-ontology .ont-item-title { + flex: 1 1 auto; + min-width: 0; +} +body.view-ontology .ont-item-pin-zone { + flex: 0 0 auto; + margin-left: auto; + display: flex; + align-items: center; + gap: 0.4rem; +} + +body.view-ontology button.ont-pin-btn, +body.view-ontology a.ont-vote-compare-btn { + background: #ebe6dc; + border: 1px solid #c8c4bc; + border-radius: 2px; + color: #3d3a34; + cursor: pointer; + font-family: var(--font-ui); + font-size: 0.72rem; + letter-spacing: 0.04em; + padding: 0.25rem 0.55rem; + text-decoration: none; + display: inline-flex; + align-items: center; + gap: 0.3rem; +} +body.view-ontology button.ont-pin-btn:hover, +body.view-ontology a.ont-vote-compare-btn:hover { + border-color: #a68e6b; + color: #1a1814; +} +body.view-ontology button.ont-pin-btn-active { + border-color: #1a4a8c; + background: color-mix(in srgb, #1a4a8c 12%, #ebe6dc); + color: #0d2d5c; +} +body.view-ontology button.ont-pin-btn:focus-visible, +body.view-ontology a.ont-vote-compare-btn:focus-visible { + outline: 2px solid #1a4a8c; + outline-offset: 2px; +} + +body.view-ontology .ont-garden-child-actions { + display: inline-flex; + align-items: center; + margin-right: 0.35rem; + vertical-align: middle; + gap: 0.1rem; +} +body.view-ontology button.ont-garden-pin-ico, +body.view-ontology a.ont-garden-vote-ico, +body.view-ontology span.ont-garden-pinned-here { + font-size: 0.95rem; + line-height: 1; + padding: 0.1rem 0.35rem; + min-width: 1.65rem; + min-height: 1.65rem; + display: inline-flex; + align-items: center; + justify-content: center; + border: 1px solid #c8c4bc; + border-radius: 2px; + background: #f7f3eb; + cursor: pointer; + text-decoration: none; + color: #1a1814; +} +body.view-ontology a.ont-garden-vote-ico:hover { + border-color: #a68e6b; + background: #ebe6dc; +} +body.view-ontology span.ont-garden-pinned-here { + border-color: #1a4a8c; + background: color-mix(in srgb, #1a4a8c 10%, #f7f3eb); + cursor: default; +} +body.view-ontology form.ont-garden-pin-form { + display: inline; + margin: 0; + padding: 0; +} +body.view-ontology button.ont-garden-pin-ico:focus-visible { + outline: 2px solid #1a4a8c; + outline-offset: 2px; +} + +body.view-ontology ol.ont-ranking-list li, +body.view-ontology ul.ont-group-list li { + display: flex; + align-items: baseline; + gap: 0.35rem; +} +body.view-ontology ol.ont-ranking-list li .item-link, +body.view-ontology ul.ont-group-list li .item-link { + flex: 1; + min-width: 0; +} + +body.view-ontology code, +body.view-ontology .vote-compare-item code, +body.view-ontology .vote-edge-meta code { + background: #ebe6dc; + color: #1a1814; + border: 1px solid #d4cfc4; + padding: 0.12em 0.35em; + font-size: 0.88em; +} + +body.view-ontology div.ratio-bar { + background: #e3ded4; + border: 1px solid #c8c4bc; +} +body.view-ontology div.ratio-left, +body.view-ontology div.ratio-right { + background: #cec9bf; +} +body.view-ontology div.ratio-left.current, +body.view-ontology div.ratio-right.current { + background: #9a7b4a; +} + +body.view-ontology.view-vote-compare .vote-compare-shell { + margin: 0.75rem 0 1.5rem; + max-width: 36rem; + padding: 0.85rem 1rem 1.1rem; + background: #f7f3eb; + border: 1px solid #c8c4bc; + border-radius: 3px; + box-shadow: 0 1px 0 rgba(26, 24, 20, 0.06); +} +body.view-ontology.view-vote-compare .vote-compare-shell > h2 { + margin-top: 0; + font-size: 0.7rem; + letter-spacing: 0.16em; + text-transform: uppercase; + color: #5c574e; +} +body.view-ontology .vote-compare-pair { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.65rem 1rem; + margin: 0.65rem 0 0.85rem; +} +body.view-ontology .vote-compare-vs { + color: #8a857a; + font-family: var(--font-ui); + font-size: 0.72rem; + letter-spacing: 0.1em; + text-transform: uppercase; +} +body.view-ontology .vote-compare-item { + text-decoration: none; +} +body.view-ontology .vote-compare-item:hover code { + border-color: #a68e6b; + background: #f0ebe3; +} + +body.view-ontology .vote-thread-picker { + margin: 0.85rem 0; + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem 0.75rem; +} +body.view-ontology .vote-thread-picker-label { + font-family: var(--font-ui); + font-size: 0.72rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: #5c574e; +} +body.view-ontology #vote-thread-select { + min-width: 10rem; + background: #f7f3eb; + border: 1px solid #c8c4bc; + color: #1a1814; + font-family: var(--font-ui); + font-size: 0.78rem; + padding: 0.3rem 0.45rem; +} + +body.view-ontology .vote-compare-slider-label { + display: flex; + flex-wrap: wrap; + align-items: center; + gap: 0.5rem 0.65rem; + margin: 0.85rem 0; + font-family: var(--font-ui); + font-size: 0.72rem; + color: #5c574e; +} +body.view-ontology #vote-preference-slider { + flex: 1 1 11rem; + min-width: 8rem; + accent-color: #9a7b4a; +} + +body.view-ontology .vote-explain-label { + display: block; + font-family: var(--font-ui); + font-size: 0.72rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: #5c574e; + margin: 0.65rem 0 0.35rem; +} +body.view-ontology #vote-compare-form textarea, +body.view-ontology.view-vote-compare textarea#vote-explain { + background: #fdfcfa; + border: 1px solid #c8c4bc; + color: #1a1814; + font-family: var(--font-prose); + font-size: 0.9rem; + line-height: 1.45; + width: 100%; + max-width: 100%; + padding: 0.55rem 0.65rem; + margin-top: 0.25rem; +} +body.view-ontology #vote-compare-form textarea:focus { + border-color: #a68e6b; + outline: none; + box-shadow: 0 0 0 2px color-mix(in srgb, #a68e6b 28%, transparent); +} + +body.view-ontology #vote-compare-form button[type="submit"] { + background: #1a1814; + border: 1px solid #1a1814; + color: #f7f3eb; + font-family: var(--font-ui); + font-size: 0.78rem; + letter-spacing: 0.06em; + padding: 0.4rem 1rem; + margin-top: 0.35rem; +} +body.view-ontology #vote-compare-form button[type="submit"]:hover { + background: #2a2620; + border-color: #2a2620; + color: #fff; +} + +body.view-ontology #vote-edge-history-region { + margin: 0.75rem 0 1rem; + padding-bottom: 0.35rem; + border-bottom: 1px dashed #d4cfc4; +} +body.view-ontology .vote-edge-history-title { + font-size: 0.72rem; + letter-spacing: 0.12em; + text-transform: uppercase; + color: #5c574e; + margin: 0 0 0.5rem; +} +body.view-ontology ol.vote-edge-history { + margin: 0; + padding-left: 1.1rem; +} +body.view-ontology li.vote-edge-history-row { + margin: 0.65rem 0; + padding-left: 0.15rem; +} +body.view-ontology .vote-edge-meta { + font-size: 0.78rem; + line-height: 1.5; +} +body.view-ontology .vote-edge-ratio { + margin: 0 0.35rem; + font-weight: 600; + color: #1a1814; +} +body.view-ontology .vote-edge-bar { + margin-top: 0.25rem; + max-width: 100%; + border-radius: 2px; + overflow: hidden; +} +body.view-ontology .vote-edge-reason { + margin-top: 0.35rem; + font-size: 0.78rem; +} +body.view-ontology .vote-compare-preview-wrap { + margin: 0.85rem 0; +} +body.view-ontology .vote-compare-preview-wrap h3 { + font-size: 0.72rem; + letter-spacing: 0.08em; + text-transform: uppercase; + color: #5c574e; + margin: 0 0 0.4rem; +} +body.view-ontology #vote-compare-preview { + min-height: 2.5rem; +}