Side A makes a real, targeted fix: removing a dead/unused CSS wrapper section in the vote-compare template and consistently restyling the ranking-number markers across three theme files, producing a concrete visible/behavioral improvement. Side B is almost entirely mechanical rustfmt/reformatting noise across many files plus minor tooling config (toolchain components, VS Code settings) and one small CSS dedup, which has some value (tooling reliability) but contributes little functional substance and is largely reformatting churn.
constitution · epochs · watch · epoch 3
c_e4fb43f04791 (tommy-mor) vs c_9e1ff4fc0186 (tommy-mor)
download prompt · raw event · cmp_50837f9951d191
council reasoning
Side A removes an unnecessary vote-compare-shell wrapper from the HTML template and ships real cross-theme CSS for ontology ranking lists (larger tabular rank numbers, missing ol.ont-ranking-list rules in retro/craft). Side B is almost entirely mechanical rustfmt whitespace/import churn plus minor toolchain pinning and a duplicate CSS merge, which adds little lasting product value.
Side A makes a user-visible structural change by removing the unnecessary `vote-compare-shell` wrapper from the vote comparison page and updates theme CSS to implement consistent numbered ranking lists across the default, retro, and retro_craft themes with improved counter styling. Side B is overwhelmingly a workspace-wide rustfmt reformat plus tooling configuration (pinning rustfmt/clippy, VS Code settings, minor CSS rule merge), with little functional impact beyond development ergonomics.
sides
A — c_e4fb43f04791 (tommy-mor)
message
[09842c93] remove shell
diff preview
diff --git a/server/src/html/garden.rs b/server/src/html/garden.rs
index 8fc6be1de8dd975f9547de615809222236be4b70..76ba96e45c9e16291a6ccd8096fdd01b274c1560 100644
--- a/server/src/html/garden.rs
+++ b/server/src/html/garden.rs
@@ -1321,55 +1321,53 @@ async fn vote_compare_inner(
.expect("vote compare rpc json");
let body = html! {
- section class="vote-compare-shell" {
- h2 { "compare" }
- div class="vote-compare-pair" {
- a class="vote-compare-item" href=(nav.garden_item_href(&left)) {
- code { (item_display_path(left.as_str())) }
- }
- span class="vote-compare-vs" { "vs" }
- a class="vote-compare-item" href=(nav.garden_item_href(&right)) {
- code { (item_display_path(right.as_str())) }
- }
- }
- div id="vote-edge-history-region" {
- (edge_history)
- }
- @if can_post {
- form id="vote-compare-form" method="POST" action="/ui" {
- input type="hidden" name=(UI_RPC_FIELD) value=(rpc_json);
- div class="vote-thread-picker" {
- label class="vote-thread-picker-label" { "thread" }
- select id="vote-thread-select" name="thread_tag" aria-label="Thread to post vote into" {
- @if thread_tags.is_empty() {
- option value="vote" selected { "#vote" }
- }
- @for t in &thread_tags {
- @if *t == auto_thread {
- option value=(t) selected { "#" (t) }
- } @else {
- option value=(t) { "#" (t) }
- }
- }
- }
+ h2 { "compare" }
+ div class="vote-compare-pair" {
+ a class="vote-compare-item" href=(nav.garden_item_href(&left)) {
+ code { (item_display_path(left.as_str())) }
+ }
+ span class="vote-compare-vs" { "vs" }
+ a class="vote-compare-item" href=(nav.garden_item_href(&right)) {
+ code { (item_display_path(right.as_str())) }
+ }
+ }
+ div id="vote-edge-history-region" {
+ (edge_history)
+ }
+ @if can_post {
+ form id="vote-compare-form" method="POST" action="/ui" {
+ input type="hidden" name=(UI_RPC_FIELD) value=(rpc_json);
+ div class="vote-thread-picker" {
+ label class="vote-thread-picker-label" { "thread" }
+ select id="vote-thread-select" name="thread_tag" aria-label="Thread to post vote into" {
+ @if thread_tags.is_empty() {
+ option value="vote" selected { "#vote" }
}
- input type="hidden" name="ratio_left" id="vote-ratio-left" value="50";
- input type="hidden" name="ratio_right" id="vote-ratio-right" value="50";
- label class="vote-compare-slider-label" {
- span id="vote-slider-left-label" { (item_display_path(left.as_str())) }
- input type="range" id="vote-preference-slider" min="0" max="100" value="50"
- aria-valuemin="0" aria-valuemax="100";
- span id="vote-slider-right-label" { (item_display_path(right.as_str())) }
+ @for t in &thread_tags {
+ @if *t == auto_thread {
+ option value=(t) selected { "#" (t) }
+ } @else {
+ option value=(t) { "#" (t) }
+ }
}
- label class="vote-explain-label" { "reason (required)" }
- textarea name="explanation" id="vote-explain" rows="5" placeholder="why this split?" required {}
- div id="vote-compare-errors" {}
- p { button type="submit" { "post vote" } }
}
- } @else {
- p class="muted" { a href="/login" { "log in" } " to post this vote." }
}
+ input type="hidden" name="ratio_left" id="vote-ratio-left" value="50";
+ input type="hidden" name="ratio_right" id="vote-ratio-right" value="50";
+ label class="vote-compare-slider-label" {
+ span id="vote-slider-left-label" { (item_display_path(left.as_str())) }
+ input type="range" id="vote-preference-slider" min="0" max="100" value="50"
+ aria-valuemin="0" aria-valuemax="100";
+ span id="vote-slider-right-label" { (item_display_path(right.as_str())) }
+ }
+ label class="vote-explain-label" { "reason (required)" }
+ textarea name="explanation" id="vote-explain" rows="5" placeholder="why this split?" required {}
+ div id="vote-compare-errors" {}
+ p { button type="submit" { "post vote" } }
}
+ } @else {
+ p class="muted" { a href="/login" { "log in" } " to post this vote." }
+ }
};
let page = layout_full_bleed_chromeless(
diff --git a/server/static/theme_default.css b/server/static/theme_default.css
index a441c4f79d8cf88f5a8240f9992f47dbbd1ab46b..fdcde86c718eb53cce8273e45a9844c2d8041f88 100644
--- a/server/static/theme_default.css
+++ b/server/static/theme_default.css
@@ -1270,8 +1270,12 @@ body.view-ontology-dark .ont-ranking-list li {
body.view-ontology-dark .ont-ranking-list li::before {
color: var(--meta);
content: counter(ont-rank) ".";
- font-size: 11px;
- min-width: 18px;
+ flex-shrink: 0;
+ font-size: 1.35rem;
+ font-weight: 700;
+ font-variant-numeric: tabular-nums;
+ line-height: 1;
+ min-width: 2.25ch;
text-align: right;
}
body.view-ontology-dark .ont-rank-score {
@@ -1424,8 +1428,12 @@ body.view-ontology-light .ont-ranking-list li {
body.view-ontology-light .ont-ranking-list li::before {
color: var(--meta);
content: counter(ont-rank) ".";
- font-size: 11px;
- min-width: 18px;
+ flex-shrink: 0;
+ font-size: 1.35rem;
+ font-weight: 700;
+ font-variant-numeric: tabular-nums;
+ line-height: 1;
+ min-width: 2.25ch;
text-align: right;
}
body.view-ontology-light .ont-rank-score {
diff --git a/server/static/theme_retro.css b/server/static/theme_retro.css
index 373f15bbd75b62604cdd14b9f0fadda2d6176991..61e1448b2f66a075c0e33325d6980448712fc927 100644
--- a/server/static/theme_retro.css
+++ b/server/static/theme_retro.css
@@ -135,6 +135,30 @@ body.view-ontology nav.breadcrumb a:hover {
body.view-ontology nav.breadcrumb a.bc-current { color: #111; font-weight: 600; }
body.view-ontology nav.breadcrumb .bc-sep { color: #888; padding: 0 2px; }
+body.view-ontology ol.ont-ranking-list {
+ counter-reset: ont-rank;
+ list-style: none;
+ margin: 0.5rem 0;
+ padding: 0;
+}
+body.view-ontology ol.ont-ranking-list li {
+ align-items: baseline;
+ counter-increment: ont-rank;
+ display: flex;
+ gap: 0.35rem;
+}
+body.view-ontology ol.ont-ranking-list li::before {
+ flex-shrink: 0;
+ color: #666;
+ content: counter(ont-rank) ".";
+ font-size: 1.35rem;
+ font-weight: 700;
+ font-variant-numeric: tabular-nums;
+ line-height: 1;
+ min-width: 2.25ch;
+ text-align: right;
+}
+
nav.breadcrumb.ont-sibling-nav {
margin-top: 0;
width: 100%;
diff --git a/server/static/theme_retro_craft.css b/server/static/theme_retro_craft.css
index 6eb9222184a8795d67a5d09d41de08c8ac1b148f..7da102040484c887833158a37c307d078205c701 100644
--- a/server/static/theme_retro_craft.css
+++ b/server/static/theme_retro_craft.css
@@ -742,12 +742,32 @@ body.view-ontology button.ont-garden-pin-ico:focus-visible {
outline-offset: 2px;
}
+body.view-ontology ol.ont-ranking-list {
+ counter-reset: ont-rank;
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
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 {
+ counter-increment: ont-rank;
+}
+body.view-ontology ol.ont-ranking-list li::before {
+ flex-shrink: 0;
+ color: #5c574e;
+ content: counter(ont-rank) ".";
+ font-size: 1.35rem;
+ font-weight: 700;
+ font-variant-numeric: tabular-nums;
+ line-height: 1;
+ min-width: 2.25ch;
+ text-align: right;
+}
body.view-ontology ol.ont-ranking-list li .item-link,
body.view-ontology ul.ont-group-list li .item-link {
flex: 1;
B — c_9e1ff4fc0186 (tommy-mor)
message
[2a94401b] Run rustfmt workspace-wide and fix lint tooling. Pin rustfmt and clippy in rust-toolchain.toml after a broken component install, merge a duplicate vote-slider CSS rule, and add VS Code settings so rust-analyzer uses the project toolchain. Co-authored-by: Cursor <cursoragent@cursor.com>
diff preview
diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000000000000000000000000000000000000..98ebd754a6d5a972550506c69c5a10c10e3210b6
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,8 @@
+{
+ "rust-analyzer.rustc.source": "discover",
+ "rust-analyzer.check.command": "check",
+ "rust-analyzer.procMacro.enable": true,
+ "rust-analyzer.cargo.extraEnv": {
+ "RUSTUP_TOOLCHAIN": "1.88.0"
+ }
+}
diff --git a/durable/examples/combined_example.rs b/durable/examples/combined_example.rs
index 626a6e1cf7e3c9c26f9f2edc58950d9bc31ec67e..6e9cb3210714d74c9a2cc0ed4f87e1b8d84788da 100644
--- a/durable/examples/combined_example.rs
+++ b/durable/examples/combined_example.rs
@@ -1,5 +1,5 @@
use durable::{Db, DurableMap, DurableVec};
-use serde::{Serialize, Deserialize};
+use serde::{Deserialize, Serialize};
use std::time::{SystemTime, UNIX_EPOCH};
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -28,36 +28,48 @@ fn get_timestamp() -> u64 {
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Open or create a database
let db = Db::open("chat_db")?;
-
+
// Create our collections
let mut users = DurableMap::<String, User>::new(&db, "users")?;
let mut messages = DurableVec::<Message>::new(&db, "messages")?;
let mut user_message_indices = DurableMap::<String, Vec<usize>>::new(&db, "user_messages")?;
-
+
// Create some users
- users.insert("alice".to_string(), User {
- username: "alice".to_string(),
- display_name: "Alice Smith".to_string(),
- message_count: 0,
- })?;
-
- users.insert("bob".to_string(), User {
- username: "bob".to_string(),
- display_name: "Bob Johnson".to_string(),
- message_count: 0,
- })?;
-
- users.insert("charlie".to_string(), User {
- username: "charlie".to_string(),
- display_name: "Charlie Brown".to_string(),
- message_count: 0,
- })?;
-
+ users.insert(
+ "alice".to_string(),
+ User {
+ username: "alice".to_string(),
+ display_name: "Alice Smith".to_string(),
+ message_count: 0,
+ },
+ )?;
+
+ users.insert(
+ "bob".to_string(),
+ User {
+ username: "bob".to_string(),
+ display_name: "Bob Johnson".to_string(),
+ message_count: 0,
+ },
+ )?;
+
+ users.insert(
+ "charlie".to_string(),
+ User {
+ username: "charlie".to_string(),
+ display_name: "Charlie Brown".to_string(),
+ message_count: 0,
+ },
+ )?;
+
// Helper to send a message
- let send_message = |from: &str, to: &str, content: &str,
+ let send_message = |from: &str,
+ to: &str,
+ content: &str,
messages: &mut DurableVec<Message>,
users: &mut DurableMap<String, User>,
- indices: &mut DurableMap<String, Vec<usize>>| -> Result<(), Box<dyn std::error::Error>> {
+ indices: &mut DurableMap<String, Vec<usize>>|
+ -> Result<(), Box<dyn std::error::Error>> {
// Create message
let msg_id = messages.len()? as u64;
let message = Message {
@@ -67,61 +79,93 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
content: content.to_string(),
timestamp: get_timestamp(),
};
-
+
// Store message
messages.push(message)?;
let msg_index = messages.len()? - 1;
-
+
// Update sender's message count
if let Some(mut sender) = users.get(&from.to_string())? {
sender.message_count += 1;
users.insert(from.to_string(), sender)?;
}
-
+
// Track message indices for recipient
let mut recipient_indices = indices.get(&to.to_string())?.unwrap_or_default();
recipient_indices.push(msg_index);
indices.insert(to.to_string(), recipient_indices)?;
-
+
Ok(())
};
-
+
// Send some messages
println!("💬 Chat Application Demo\n");
println!("Sending messages...");
-
- send_message("alice", "bob", "Hey Bob, how's the Durable library coming along?",
- &mut messages, &mut users, &mut user_message_indices)?;
-
- send_message("bob", "alice", "It's going great! We have DurableVec and DurableMap working!",
- &mut messages, &mut users, &mut user_message_indices)?;
-
- send_message("charlie", "alice", "That sounds awesome! Can I help with testing?",
- &mut messages, &mut users, &mut user_message_indices)?;
-
- send_message("alice", "charlie", "Absolutely! The more testing the better!",
- &mut messages, &mut users, &mut user_message_indices)?;
-
- send_message("bob", "charlie", "Check out the examples directory for usage patterns",
- &mut messages, &mut users, &mut user_message_indices)?;
-
+
+ send_message(
+ "alice",
+ "bob",
+ "Hey Bob, how's the Durable library coming along?",
+ &mut messages,
+ &mut users,
+ &mut user_message_indices,
+ )?;
+
+ send_message(
+ "bob",
+ "alice",
+ "It's going great! We have DurableVec and DurableMap working!",
+ &mut messages,
+ &mut users,
+ &mut user_message_indices,
+ )?;
+
+ send_message(
+ "charlie",
+ "alice",
+ "That sounds awesome! Can I help with testing?",
+ &mut messages,
+ &mut users,
+ &mut user_message_indices,
+ )?;
+
+ send_message(
+ "alice",
+ "charlie",
+ "Absolutely! The more testing the better!",
+ &mut messages,
+ &mut users,
+ &mut user_message_indices,
+ )?;
+
+ send_message(
+ "bob",
+ "charlie",
+ "Check out the examples directory for usage patterns",
+ &mut messages,
+ &mut users,
+ &mut user_message_indices,
+ )?;
+
// Display all users and their message counts
println!("\n👥 Users:");
let mut all_users = users.to_vec()?;
all_users.sort_by_key(|(username, _)| username.clone());
-
+
for (username, user) in all_users {
- println!(" {} ({}) - {} messages sent",
- user.display_name, username, user.message_count);
+ println!(
+ " {} ({}) - {} messages sent",
+ user.display_name, username, user.message_count
+ );
}
-
+
// Display all messages
println!("\n📨 All messages:");
for (i, msg) in messages.iter()?.enumerate() {
let msg = msg?;
println!(" [{}] {} → {}: {}", i, msg.from, msg.to, msg.content);
}
-
+
// Show inbox for each user
println!("\n📥 User inboxes:");
for item in users.iter() {
@@ -135,26 +179,26 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
}
}
}
-
+
// Statistics
println!("\n📊 Statistics:");
println!(" Total users: {}", users.len()?);
println!(" Total messages: {}", messages.len()?);
-
+
// Demonstrate persistence
println!("\n💾 Data has been persisted to disk!");
println!(" Database location: ./chat_db");
-
+
// Clean up
drop(messages);
drop(users);
drop(user_message_indices);
drop(db);
-
+
// Remove the database for this example
std::fs::remove_dir_all("chat_db").ok();
-
+
println!("\n✅ Example completed!");
-
+
Ok(())
-}
\ No newline at end of file
+}
diff --git a/durable/examples/map_example.rs b/durable/examples/map_example.rs
index 08b8f2c8826caf53c4c20b422a540c92f6624029..1d9c4a14b0f4cfe39ade84ebb1f1a14033e8ff1b 100644
--- a/durable/examples/map_example.rs
+++ b/durable/examples/map_example.rs
@@ -1,5 +1,5 @@
use durable::{Db, DurableMap};
-use serde::{Serialize, Deserialize};
+use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
struct UserProfile {
@@ -11,10 +11,10 @@ struct UserProfile {
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Open or create a database
let db = Db::open("example_db")?;
-
+
// Create a persistent map of user profiles
let mut users = DurableMap::<String, UserProfile>::new(&db, "users")?;
-
+
// Insert some users
// Using put() when we don't need the old value - more efficient!
users.put(
@@ -25,7 +25,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
score: 1500,
},
)?;
-
+
users.put(
"bob".to_string(),
UserProfile {
@@ -34,7 +34,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
score: 1200,
},
)?;
-
+
// Using insert() when we might need the old value
let old_charlie = users.insert(
"charlie".to_string(),
@@ -44,21 +44,24 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
score: 1800,
},
)?;
-
+
if old_charlie.is_some() {
println!("Replaced existing charlie entry");
}
-
+
println!("Total users: {}", users.len()?);
-
+
// Look up a specific user
if let Some(alice) = users.get(&"alice".to_string())? {
println!("\nAlice's profile: {:?}", alice);
}
-
+
// Check if a user exists
- println!("\nDoes 'david' exist? {}", users.contains_key(&"david".to_string())?);
-
+ println!(
+ "\nDoes 'david' exist? {}",
+ users.contains_key(&"david".to_string())?
+ );
+
// Update a user's score
if let Some(mut bob) = users.get(&"bob".to_string())? {
bob.score += 100;
@@ -66,34 +69,40 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
users.put("bob".to_string(), bob)?;
println!("Updated Bob's score!");
}
-
+
// Iterate over all users
println!("\nAll users (sorted by username):");
let mut all_users = users.to_vec()?;
all_users.sort_by_key(|(username, _)| username.clone());
-
+
for (username, profile) in all_users {
- println!(" {} ({}) - Score: {}", username, profile.email, profile.score);
+ println!(
+ " {} ({}) - Score: {}",
+ username, profile.email, profile.score
+ );
}
-
+
// Get just the usernames
let mut usernames = users.keys_vec()?;
usernames.sort();
println!("\nAll usernames: {:?}", usernames);
-
+
// Find the highest scoring user
let profiles = users.values_vec()?;
if let Some(top_user) = profiles.iter().max_by_key(|p| p.score) {
- println!("\nTop scorer: {} with {} points", top_user.name, top_user.score);
+ println!(
+ "\nTop scorer: {} with {} points",
+ top_user.name, top_user.score
+ );
}
-
+
// Remove a user
if let Some(removed) = users.remove(&"charlie".to_string())? {
println!("\nRemoved user: {}", removed.name);
println!("Users remaining: {}", users.len()?);
}
-
+
println!("\nData has been persisted to disk.");
-
+
Ok(())
-}
\ No newline at end of file
+}
diff --git a/durable/examples/nested_example.rs b/durable/examples/nested_example.rs
index 3b880f2c8b8ad2633d4b5fcf2016652216c9de8e..f16090cf6fb854ac7a1b00acfd31fbd12c25dbce 100644
--- a/durable/examples/nested_example.rs
+++ b/durable/examples/nested_example.rs
@@ -3,27 +3,31 @@ use durable::{Db, DurableMap, DurableVec};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// Open a database
let db = Db::open("nested_example_db")?;
-
+
// Create a map where each user has a list of posts
- let user_posts: DurableMap<String, DurableVec<String>> = DurableMap::new_nested(&db, "user_posts");
-
+ let user_posts: DurableMap<String, DurableVec<String>> =
+ DurableMap::new
… preview truncated; 96,900 characters omittedHardlinks — judgments / attempts / prompt
judgments
attempts
Prompt text is loaded only by the download route.