comparison · c_3f420a1f5aa1 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Commit A introduces substantial new functionality across the project. It adds server-backed theme selection with cookie persistence, updates many HTML handlers to propagate theme state, preserves theme cookies through authentication flows, adds a new POST /theme endpoint, replaces client-only theme switching with a server-integrated implementation, introduces room-aware URL generation helpers with tests, and updates many RPC responses and page renderers to produce correct room-specific links. The changes span authentication, routing, HTML rendering, RPC behavior, utilities, CSS, and documentation comments.
Commit B is a focused refinement. It improves the garden UI by showing pairwise vote counts, changes the pinned-item HUD from a permalink into an unpin action, adds supporting CSS, a helper function with a unit test, updates browser tests, and makes a small documentation correction. These are useful UX and correctness improvements, but they are much narrower in scope and impact than the broad architectural and feature work in Commit A.
Side A introduces a substantial cross-cutting feature set: a full theme system with cookie persistence, request/response propagation, layout changes, new endpoints, and consistent integration across many HTML views and auth flows. It also adds room-aware URL handling throughout the RPC layer, affecting core API behavior. Side B is more incremental—UI/UX improvements (vote counts, HUD unpin behavior), small helper logic, and tests. While useful, it’s localized compared to A’s broad architectural impact.
Side A introduces a comprehensive theme system (cookie handling, POST /theme, layout refactor, JS/CSS changes), propagates theme context across nearly all HTML handlers, and adds room-aware URL handling throughout the RPC/API layer with new helpers and tests. It touches many core files and changes routing, rendering, and JSON outputs. Side B focuses on garden pin UX improvements (vote counts, HUD unpin via POST), related JS/CSS tweaks, and a targeted test—meaningful but much narrower in scope and architectural impact. Overall, Side A is substantially larger and more foundational.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_0957178bd303 (tommy-mor)
Commit A delivers a substantial functional improvement across multiple parts of the project. It adds pairwise vote counts to the garden UI, introduces a helper with unit tests, changes the pin HUD from a navigation link to an unpin action using POST /ui, updates JavaScript, styles for two themes, documentation, and browser tests. These changes affect behavior, usability, and test coverage. Commit B is a focused UI layout fix that moves the view counter into the top navigation and adjusts CSS to prevent overlap with authentication controls. It is a useful polish change but much smaller in scope and impact.
Commit A introduces a meaningful feature (pairwise vote counts in the UI), adds a new helper function, threads data through rendering, updates multiple UI components (HTML, JS, CSS), and includes tests to validate behavior. It also refines existing interactions (pin HUD behavior). Commit B is a small layout adjustment moving an existing view counter into the nav to fix overlap. The scope, complexity, and impact of A are significantly greater.
Side A introduces substantial functional enhancements: adds edge vote counting logic with tests, updates garden UI to display per-pair vote counts, refactors pin HUD behavior to POST-based unpin with JS changes, and includes extensive CSS updates across themes plus browser test coverage. Side B is a small layout adjustment moving the view counter into the top nav with minor CSS tweaks. The scope, complexity, and user-facing impact of A are significantly greater.
comparison · c_3f420a1f5aa1 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Commit A implements a substantial, coherent feature (server-rendered theme selection replacing client-only JS theme switching, with cookie persistence, proper redirect/session cookie propagation, and room-aware wire URL helpers with dedicated unit tests) touching many call sites correctly. Commit B is a smaller UX polish (vote counts on garden rows, HUD unpin-via-form instead of link) plus one doc tweak and a browser test update, which is useful but narrower in scope and lasting impact than A's structural change to theming and API URL handling.
A lands lasting infrastructure: cookie/server-rendered themes (with login cookie re-issue and POST /theme) plus correct private-room wire URLs via item_path_for_api_in_room/forum_thread_web_url threaded through RPC and accompanied by tests. B is real but narrower UX polish—vote counts on garden compare icons and turning the pin HUD into an unpin POST—valuable with tests, yet not as foundational as A’s product-wide path and theme design.
Side A introduces substantial, project-wide functionality: persistent theme selection via validated cookies and a new `/theme` endpoint, propagates theme state through authentication so login no longer drops the theme, and correctly generates room-scoped URLs across RPC responses with dedicated helpers and tests. Side B is a focused UI refinement that adds vote counts to garden compare links, changes the pin HUD into an unpin action, and updates CSS/tests, but its impact is localized compared with A's cross-cutting infrastructure and correctness improvements.
Side A introduces substantial cross-cutting functionality: a full theme system (cookie handling, POST /theme, layout changes) and correct room-aware URL generation by replacing item_path_for_api with item_path_for_api_in_room throughout RPC and helpers. Side B is a focused UI improvement (vote counts, HUD unpin behavior) with a small helper and test, but far less impactful to core behavior.
Side A introduces a full server-backed theme system (new /theme route, cookie normalization, layout changes, and propagation through all HTML handlers) and adds room-aware URL handling across RPC via `item_path_for_api_in_room` and `forum_thread_web_url`, affecting many endpoints and responses. Side B mainly enhances the garden UI with vote counts and a HUD unpin form plus related CSS/tests, which is valuable UX polish but narrower in scope and architectural impact than A’s cross-cutting design changes.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_0957178bd303 (tommy-mor)
Side A adds substantive functionality (vote-count tooltips/badges with backing helper function and unit test) and a real UX fix (HUD unpin becomes a proper POST action with browser test coverage), touching multiple files with tests validating behavior. Side B is a small, useful but narrow CSS/layout fix moving a view counter into the nav to avoid overlap, with no tests and much less scope.
A adds lasting product behavior: pairwise vote counts on garden rows (with a real helper + unit test), turns the pin HUD into a proper unpin POST instead of a misleading permalink (plus browser coverage), and supporting CSS/docs. B only relocates the view counter into the top nav and drops fixed positioning to stop overlap—a correct but tiny layout fix.
Side A implements substantive UI and behavior improvements: it adds pairwise vote counts to garden voting controls backed by a new helper and test, changes the pin HUD from a permalink into a functional unpin action via `POST /ui set_garden_pin clear:true`, updates styling, documentation, and browser tests to support the new behavior. Side B is a small layout fix that simply moves the view counter into the existing top navigation and adjusts CSS to prevent overlap with authentication links.
A introduces new functionality and correctness checks: it computes and displays per-pair vote counts (`edge_vote_count_for_pair`), updates the UI to show counts and proper unpin behavior via POST, and adds tests verifying vote counting and HUD behavior. B only repositions an existing view counter into the nav and removes fixed positioning, a minor UI tweak without deeper impact.
Side A adds substantive functionality: a new `edge_vote_count_for_pair` helper with tests, surfaces pairwise vote counts in the garden UI, converts the HUD pin link into a proper POST `set_garden_pin clear` action with supporting JS/CSS changes, and extends browser tests to verify unpin behavior. Side B only repositions the view counter into the top nav and removes fixed positioning in CSS to avoid overlap, a small layout tweak without deeper logic or tests.
comparison · c_4ed2e2cca39b (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Commit A is a small, precise bugfix that resolves a real NameError crash in the OAuth callback by defining the missing GITHUB_API_BASE_URL, directly fixing broken functionality. Commit B bundles multiple UI feature additions (vote counts, HUD unpin button) with unrelated churn and no clear single bugfix, making it more diffuse and harder to attribute lasting, focused value despite its larger size.
B adds lasting product behavior: edge vote counts on garden rows (with a real helper + unit test), HUD unpin via POST clear instead of a misleading permalink, matching CSS/JS, and browser coverage. A only introduces a missing GITHUB_API_BASE_URL default—a correct but tiny config fix with far less project impact.
Side B implements substantive product behavior across the UI: it adds pairwise vote counts in the garden view, changes the pinned-item HUD from a permalink to an unpin action via `POST /ui`, updates styling, and adds both unit and browser tests to verify the new behavior. Side A is a small but useful bug fix that defines `GITHUB_API_BASE_URL` with a default to prevent a `NameError`, but its scope and long-term impact are much narrower.
comparison · c_ebc883667d61 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Side A is essentially cleanup: deleting a stray duplicate forum.rs so the earlier module split resolves (necessary, but it's dead-code removal/reorg with no new behavior). Side B lands multiple concrete fixes—unpinning via a POST RPC instead of a stale link (real UX/correctness bug), a vote-count tooltip/UI enhancement, matching CSS, and a new unit test plus an updated browser test asserting the corrected unpin behavior—delivering more verifiable, lasting functional value.
Side B delivers lasting product behavior: garden pin HUD becomes an unpin `POST /ui set_garden_pin clear` action (with browser coverage), pairwise vote counts on garden rows via `edge_vote_count_for_pair` plus a unit test, and matching docs/CSS. Side A is mostly module hygiene—deleting leftover monolithic `forum.rs` and re-homing the same logic under `forum/`—so it clarifies resolution but adds little new capability versus B’s user-facing fixes.
Side A resolves a structural correctness issue by removing the duplicate `server/src/html/forum.rs` module, adding `forum/mod.rs`, and making the split `forum/` directory the single module root. This eliminates ambiguous module resolution and consolidates the existing implementation into a maintainable layout, whereas Side B mainly adds UI enhancements (HUD unpin button, vote counts/tooltips, CSS, and tests) without addressing a foundational project structure problem.
comparison · c_cf0a514b261a (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Side B delivers multiple real feature improvements (vote-count tooltips/badges on garden pin icons, converting the pin HUD link into a proper unpin form action, plus matching CSS and new/expanded automated tests) that add durable, well-tested functionality. Side A is a small, well-justified but minor dead-code removal in the reducer with a corresponding test update—correct and clean, but far more limited in scope and impact.
B adds durable product value: pairwise vote counts on garden vote controls, pin-HUD unpin (clear) instead of a misleading item link, themed CSS, and browser/unit coverage. A only deletes a already-redundant zero-ratio early-return in the reducer and retunes one test—correct hygiene, but far less lasting impact.
Side B adds substantive user-facing functionality and supporting infrastructure: it replaces the pin HUD permalink with an unpin POST action, displays pairwise vote counts in the garden UI via a new `edge_vote_count_for_pair` helper, updates CSS/JS, and adds both unit and browser tests to verify the behavior. Side A is a small cleanup that removes a redundant zero-ratio guard in `apply_vote` and adjusts tests to reflect existing parser and edge-handling behavior, which is useful but much narrower in lasting impact.
comparison · c_6a02ffb06a41 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Side B fixes a real UX bug (HUD 'pinned item' link navigating away instead of properly unpinning, replaced with a correct POST-based unpin form), adds a genuinely useful vote-count indicator with backing unit test, and includes corresponding CSS and browser-test coverage. Side A is a smaller, more localized change replacing a fallback default with a panic/expect and updating doc comments/tests, which is reasonable but lower-impact and riskier (introducing a potential panic) compared to B's broader, well-tested feature fix.
A permanently reconciles rank-history thread_post_index with the 0-based /t/tag/N routes (types, RPC, garden recv view), replaces silent unwrap_or(0)/1-based offsets with a hard expect, and locks the contract in integration asserts—fixing link bugs class. B adds solid UX (edge vote counts, HUD unpin via set_garden_pin clear) plus tests/CSS, but it is product surface polish rather than a shared data/URL invariant fix.
Side B adds substantive user-facing functionality: it introduces pairwise vote counts in the garden UI with a tested helper (`edge_vote_count_for_pair`), changes the pin HUD to perform an unpin action via `POST /ui`, updates styling, and adds browser and unit tests covering the new behavior. Side A mainly corrects thread post indexing semantics by replacing a fallback with `expect`, always rendering the post link, updating documentation, and extending integration tests, which is valuable but much narrower in scope and lasting impact.
comparison · c_d6d339485601 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
B fixes real bugs (HUD pin link previously just re-pinned via a broken href, now properly unpins via a POST form) and adds useful UI feedback (vote counts on garden edges) with corresponding CSS, JS, and browser test coverage across multiple files. A is a smaller, purely additive CLI feature (connectivity stats display) with unit tests but lower overall impact and no bugfix component.
B fixes real garden UX (pin HUD became a clear unpin POST instead of a misleading item link) and adds lasting product signal via edge_vote_count_for_pair shown on vote icons, with server, JS, CSS, docs, and browser coverage. A only formats already-available ConnectivityStats into CLI pair output plus two unit tests—useful but narrower presentation, not a behavioral fix.
Side B delivers multiple functional improvements: it adds pairwise vote counts to garden compare links via a new `edge_vote_count_for_pair` helper, changes the pinned-item HUD into an in-place unpin action (`POST /ui set_garden_pin clear`), updates styling, and adds both unit and browser tests to verify the behavior. Side A is a useful but narrower CLI enhancement that formats and displays existing connectivity statistics with tests, exposing data already available rather than adding comparable new interaction or functionality.
comparison · c_a896b2dc05d5 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
B fixes a concrete UX bug (the HUD 'pin' link actually just navigated instead of unpinning, now properly issues a set_garden_pin clear POST) and adds a genuinely useful feature (per-edge vote counts on the compare icon), backed by both a Rust unit test and an updated browser test. A's refactor swaps a write-time-capped VecDeque for an uncapped append-only List with cap-on-read slicing, which removes bounded-growth guarantees on disk (recent_votes can now grow unboundedly, requiring a full scan/slice at read time) — a debatable tradeoff whose benefit isn't clearly established beyond the rename, despite adding a decent test for the new cap-on-read behavior.
A redesigns durable recent-votes from Deque to append-only List/Vec, drops write-path trim_recent_votes and projection batch bookkeeping, bumps schema, and caps only on read with a solid regression test—core lasting storage simplification. B is real product polish (HUD unpin fix, edge vote counts, CSS/tests) but stays UI-layer and does not change foundational durability semantics.
Side A makes a substantive persistence-model redesign by replacing the durable recent-vote deque with an append-only list, removing post-commit trimming, updating schema versioning, changing in-memory storage, and adding a test that verifies query-time capping of recent votes. Side B mainly improves UI behavior (HUD unpin action and displaying pairwise vote counts) with associated styling and browser/tests, which is useful but has less architectural impact than the storage and data-flow simplification in Side A.
comparison · c_bc8c17a00ed7 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Side B implements a real UI/UX fix (HUD unpin now POSTs a clear action instead of merely navigating), adds vote-count display on the garden vote icon with a helper function and a matching unit test, and updates CSS/browser tests accordingly, touching multiple layers coherently. Side A is a small, focused bugfix (skip pinned Reddit posts) with a good targeted test, which is solid but narrower in scope and impact than B's multi-file behavioral correction.
B delivers lasting product fixes: pairwise vote counts on garden rows (with a focused helper + unit test), HUD pin control changed from a misleading item link to a real unpin POST, matching browser coverage, and supporting CSS/docs. A is a clean, tested Reddit import filter for stickied/pinned posts, but it is a narrower data-hygiene tweak with less ongoing impact on the app.
Side B adds meaningful user-facing functionality and supporting infrastructure: it introduces pairwise vote counts in the garden UI via a new `edge_vote_count_for_pair` helper, changes the pin HUD into an in-place unpin action using `POST /ui`, updates styling, and adds both unit and browser tests to verify the behavior. Side A is a solid, targeted bug fix that skips stickied/pinned Reddit posts during import with a helper and regression test, but its scope and long-term impact are narrower.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_f515f8a12d7a (tommy-mor)
Side B removes real dead code and a duplicated code path (ExpandNewThreadForm action plus its toolbar), unifying home page compose rendering with room pages via direct SSR—reducing complexity and maintenance burden. Side A adds a legitimate feature (vote counts, unpin form) but with more surface area of speculative UI polish (CSS across two themes, vote count formatting) that is less structurally significant than B's consolidation, though A does include a solid regression test for its new helper function.
A adds lasting product behavior: correct unpin via POST set_garden_pin clear (replacing a wrong permalink HUD), pairwise edge vote counts in the garden UI with a focused helper + unit/browser tests, and supporting CSS/docs. B only deletes ExpandNewThreadForm and the home toolbar +, inlining the already-existing new-thread slot SSR—valuable cleanup but no new capability comparable to A’s fix and feature.
Side B simplifies the UI architecture by removing the `ExpandNewThreadForm` HTML action and its server-side dispatch, replacing the home page's extra toolbar with the same SSR `#new-thread-ui-slot` used on room pages. This eliminates duplicated interaction flow and dead code across `ui_html.rs`, `ui_action.rs`, and `feed.rs`, whereas Side A mainly adds UI enhancements (vote counts, HUD unpin button), styling, and supporting helpers/tests without a comparable architectural simplification.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_c25451965a7f (tommy-mor)
Side B fixes a real, broad bug: hardcoded hostnames/URLs (oauth callbacks, redirects, deploy branch) across multiple modules were centralized into a single util function that respects HOSTNAME/window.location, which is a genuine correctness/maintainability improvement affecting deploy and auth flows. Side A is a UI polish commit (vote counts, HUD unpin button, CSS tweaks, tests) that's fine but more localized cosmetic/UX churn with less structural impact than fixing broken environment-dependent redirect logic.
B fixes systemic broken redirect/OAuth base URLs by centralizing HOSTNAME-aware get-base-url (replacing divergent hardcoded sorter.social/InetAddress cases across linear/login/oauth/spotify/twitter/youtube) and making the client use window.location.origin, plus aligning deploy to staging—core correctness for multi-host. A adds useful garden UX (edge vote counts, HUD unpin via set_garden_pin clear) with tests, but it is incremental product polish rather than a cross-cutting host bugfix.
Side B removes hardcoded hostnames by centralizing base URL generation in `app.util/get-base-url`, updates multiple OAuth/callback paths to use it, and makes the frontend derive its base URL from `window.location.origin`, fixing redirects for custom hosts across the application. It also adjusts deployment to run from the staging branch. Side A adds useful UI improvements (vote counts beside compare links, HUD unpin action, tests, and styling), but these are narrower feature enhancements rather than an infrastructure fix that affects many authentication and redirect flows.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_1c1c8e7a2de8 (tommy-mor)
Side B removes dead/unused complexity (the never-really-used ThreadVisibility::Public branch, simplifying RoomState to a HashSet), adds a genuinely new CLI capability (`room create`) with corresponding RPC/reducer/timeline updates and test/doc updates across the stack. Side A is mostly UI polish (vote counts, HUD unpin button, CSS) plus doc tweaks—useful but narrower in scope and lasting impact than B's structural simplification and new feature wiring.
B adds a real CLI path (`room create`) wired to RPC and, more importantly, simplifies the lasting domain model by dropping `ThreadVisibility`/`RoomState` and making `rooms` a `HashSet` of private ids—core events, reducer, types, and tests all align. A is solid UX polish (vote-count badges, HUD unpin form, CSS, browser coverage) but does not change architecture or unlock a primary workflow the way B does.
Side B introduces a first-class `room create` CLI command wired through the RPC layer, updates the shared `RpcCommand` schema, simplifies room state by removing the unused visibility concept, and adjusts reducer, server, and tests accordingly. Side A improves the garden UI by showing pairwise vote counts and making the pin HUD unpin directly via `POST /ui`, but these are primarily interface enhancements compared with B's enduring API and data-model cleanup.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_2595b6007624 (tommy-mor)
Side B is a substantial, coherent architectural refactor: it replaces many ad-hoc REST endpoints with a unified batch RPC protocol, redesigns the reducer's scope/room model (Thread->Room, thread_id->room_id/thread_tag), and updates CLI, types, and all integration/grants tests to match — a real, consistently-applied design change with lasting structural value. Side A is a small, useful but narrow UI polish (vote-count badge, HUD unpin-via-POST bugfix) that touches a handful of files and one new helper/test, offering much less lasting architectural value than B's system-wide rework.
B replaces fragmented REST handlers with a unified batch RPC surface, remodels the event/reducer domain (rooms vs threads, room_id + thread_tag, scoped ingest indexes), and wires the CLI and tests through that design—lasting core architecture. A is useful but narrow UX polish: unpin-via-POST on the pin HUD, pairwise vote counts on garden vote icons, CSS/docs, and a browser assertion.
Side B is a substantial architectural refactor that consolidates many REST endpoints into a typed RPC interface (`/api/v0/rpc`), updates the CLI to use it, introduces room-scoped data and events (`room_id`/`thread_tag`), and adapts reducers, routing, tests, and shared types to the new model. Side A adds useful UI improvements (vote counts on compare links, HUD unpin action, tests, and styling), but these are incremental features compared with the lasting API and data-model redesign in Side B.
comparison · c_66eb04076a98 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
B delivers multiple real feature/UX fixes (unpin via HUD form instead of stale link, vote-count badges on garden compare icons, CSS/theme updates, browser test coverage) plus doc corrections, spanning several files with tested behavior changes. A is a smaller, focused but narrower refactor of a single color-gradient function with good unit tests, but it affects only cosmetic rank-row coloring in one file.
B delivers concrete product fixes: pairwise vote counts on garden row controls, correcting the pin HUD from a misleading item permalink to a real unpin POST, plus matching CSS, docs, and browser/unit coverage. A is a clean, well-tested design tweak (min–max score gradient instead of list ordinal) but narrows to ranking row color only, so it adds less lasting surface area than B’s multi-path UX and correctness work.
Side A changes the ranking color logic from list-position-based gradients to score-based min–max normalization within each group, introducing a dedicated `score_gradient_t` helper, updating rendering to use actual scores, and adding focused tests for normalization, tied scores, and stability. Side B adds several UI enhancements (vote counts, HUD unpin behavior, styling, and tests), but they are more feature-oriented and spread across multiple files, whereas Side A corrects a core visualization behavior with a clearer, reusable design.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B tightens type-safety by threading CanonicalItemUrl/GardenItemUrl newtypes (with Deref) through resolve_item, validate, rpc, and rank-change computation, eliminating stringly-typed round-tripping and reducing risk of canonicalization bugs across many call sites. Side A is a narrower UX fix (vote-count tooltip, HUD unpin behavior) with a matching unit/browser test, useful but more localized than B's structural correctness improvement.
B pushes CanonicalItemUrl through resolve_item, validate, rank-change maps, pair selection, and connectivity stats, cutting String↔newtype churn and embedding lasting type safety (plus Deref on href newtypes). A ships real UX fixes (HUD unpin via set_garden_pin clear, pairwise vote counts, CSS/tests) but is local garden/UI surface work rather than core path model cleanup.
Side B performs a substantive type-safety refactor by changing `resolve_item` to return `CanonicalItemUrl` instead of `String` and propagating canonical path types through validation, ranking, pair selection, and RPC code, eliminating repeated parsing/wrapping and reducing opportunities for path-handling mistakes. Side A mainly enhances the UI (vote counts beside compare links, HUD unpin button, CSS, browser test) with a small helper and test, which is useful but less foundational than the project-wide canonicalization and API cleanup in Side B.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_64faa3bee86f (tommy-mor)
Side A adds a concrete, tested UI improvement (vote-count badges, HUD 'unpin' turned into a proper POST action) with unit and browser-test coverage verifying the new behavior. Side B reworks the auth flow to rely on JS-only fragment morphing instead of redirects, removing the previous public_url-based redirect logic without adding any tests, which is a riskier architectural change with less verification of correctness.
B replaces redirect-based auth success/error with HTML fragments and extends the shared poem form handler to morph non-empty responses, a lasting flow design that unifies auth with the main layout and keeps existing empty-body forms working. A is solid garden UX (edge vote counts, HUD unpin via set_garden_pin clear, tests/CSS), but it is scoped feature polish rather than a core interaction-pattern fix.
Side B changes the auth flow from redirect-based responses to inline HTML fragments, extends the shared Poem form interceptor to morph returned HTML into the existing form, and factors reusable auth form rendering into fragments. This is a broader architectural improvement that enables smoother form interactions without affecting existing empty-body POST handlers, whereas Side A primarily enhances the garden UI with vote counts, HUD unpin behavior, styling, and related tests.
comparison · c_978e283f2229 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Side B ships real functional improvements: a fixed unpin control (form POST instead of a broken/odd href-based link), a new vote-count indicator on garden edges with a dedicated unit test verifying correctness, plus CSS updates across two themes and a new browser test asserting the fix. Side A is a large but essentially cosmetic CLI restructuring (renaming ingest->forum post, adding List/Show/Post subcommands, doc/DSL text rewrites) with no new tests beyond adjusting existing integration test invocations, offering clearer UX but less durable technical substance than B's bugfix-plus-test pairing.
A redesigns the CLI’s core write/browse contract (ingest → scoped `forum post`/`list`/`show`, required tag + delegate, simplified check) and lands matching docs, RPC next-move strings, and integration tests—lasting interface work. B is solid but narrower UX polish: vote-count badges on garden pins, HUD unpin via `set_garden_pin clear`, CSS, and a browser test.
Side B adds lasting functional improvements to the web UI: it changes the pin HUD from a misleading permalink into an explicit unpin action, surfaces pairwise vote counts beside compare actions by computing them from existing content state, and adds regression tests covering the new behavior. Side A is a large CLI/documentation reshape that mostly reorganizes commands and updates help text and tests to match a renamed interface, with comparatively less new functionality beyond the command structure.
comparison · c_11d6a0ec9839 (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Side B delivers more substantive functional value: a real vote-count feature (edge_vote_count_for_pair with unit test) surfaced in the UI, plus a genuine bugfix converting a dead pin-HUD link into a working unpin form with corresponding CSS and browser test coverage. Side A is a smaller cleanup (route rename, removing a button, out-of-band delegate) that is useful but narrower in scope and less tested/verified than B's changes.
A fixes lasting correctness: VOTE attribution via out-of-band delegate_opt instead of stuffing WEB_BROWSER_AGENT into DSL body text, and stops silently expanding the sibling pool to all items when <2 (returns None). B’s vote-count badges and pin-HUD→unpin are useful UX polish with tests/CSS, but they are affordance/work-surface changes rather than core behavior fixes, so A carries more durable design value despite similar surface area.
Side A fixes multiple functional issues: it correctly passes the browser agent as an out-of-band delegate option instead of embedding it in DSL text, prevents incorrect fallback to all items when the sibling comparison pool is too small by returning no next pair, removes an unnecessary swap control, and consistently renames the compare route from `/vote/compare` to `/vote` across server code and tests. Side B adds useful UI improvements such as displaying pairwise vote counts and making the pin HUD perform an unpin action, but these are primarily feature and UX enhancements rather than correcting core behavior.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
Both are similar-scope UI feature commits, but Side A introduces the underlying vote-count feature (edge_vote_count_for_pair) plus its unit test, and adds the HUD unpin-via-POST mechanism from scratch, which Side B's commit directly builds upon (reusing next_path, unpin_rpc pattern). Side A thus lays more foundational groundwork with a genuine new capability and test coverage, while Side B mainly extends the same pattern to one more UI location plus test adjustments.
A delivers two durable UX/design improvements: pairwise edge vote counts on garden rows (new helper, wiring, unit test) and correcting the pin HUD from a misleading item permalink into a real POST clear/unpin control with browser coverage and docs. B only extends the existing set_garden_pin clear flow so the ranked-list 📌 is clickable to unpin—valuable consistency, but a narrower follow-on change.
Side A delivers multiple lasting functional improvements: it adds pairwise vote counts to garden vote controls with a tested helper (`edge_vote_count_for_pair`), converts the pin HUD into a proper `POST /ui set_garden_pin clear` unpin action instead of a permalink, updates CSS for the new UI, and extends browser tests. Side B is a narrower follow-up that makes the ranked-list pinned icon submit the same unpin flow and adjusts styling/tests, but it largely builds on infrastructure introduced by Side A rather than adding comparable new capability.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_b00c261f06c2 (tommy-mor)
Side B fixes a real correctness bug (rank gradient computed across all groups instead of per-group, and vote-history bar direction misrepresenting ratios) and adds targeted unit tests validating the polarity/slider mapping, which is a genuine bugfix with lasting value. Side A is mostly UI polish (vote counts, HUD unpin button, docs tweak) which is useful but more incremental/cosmetic than a correctness fix.
B fixes core vote-compare correctness: rank-row gradients scoped per group, slider polarity/winner mapping aligned with HUD semantics, and history bars replaced by the same center-anchored slider model, backed by polarity and ranking invariant tests. A is valuable UX polish (unpin via POST clear, pairwise vote counts on garden icons, docs/CSS/browser coverage) but is additive surface rather than repairing the ranking/vote visualization contract.
Side B fixes a concrete correctness issue in vote comparison by making highlight gradients operate per ranking group instead of globally, aligns vote-history visualization with actual left/right vote polarity through new mapping helpers, and adds focused tests for orientation and ranking invariants. Side A adds useful UI enhancements (vote counts beside compare links and an unpin action in the HUD) plus tests, but these are primarily feature and usability improvements rather than a core correctness fix.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_e2ee16c7ada5 (tommy-mor)
Side B is a substantive architectural refactor: it splits identity/path normalization into dedicated modules, removes double-canonicalization bugs (reducer no longer re-rewrites identity), fixes wire format inconsistencies (@ vs no-@ across JSON APIs), makes delegate optional for human-only ingests, and updates CLI/tests/docs consistently across the codebase. Side A is a smaller UI polish commit (vote counts on garden pins, unpin-via-HUD-form instead of link) with modest test/CSS additions but no structural or correctness improvement of comparable scope.
B is a lasting architectural cleanup: new canonical_path/identity modules, strict no-@ wire/storage forms, optional delegate on Ingest, and reducer that stops rewriting identity—touching API contracts, events, CLI, and tests consistently. A only adds localized garden UX (edge vote counts on vote icons, HUD unpin via set_garden_pin clear) plus CSS and a browser test, which is useful polish but far less structural.
Side B makes a substantial architectural change by separating path canonicalization and identity parsing into new `canonical_path.rs` and `identity.rs`, removing identity rewriting from the reducer, making delegate identities optional, and consistently enforcing stored-form usernames/agent IDs across APIs, CLI, types, and tests. Side A adds useful UI improvements (pairwise vote counts in the garden, an unpin action in the HUD, styling, and tests), but those are localized feature enhancements rather than a broad, lasting design improvement.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_8c6a5e2e4a54 (tommy-mor)
Commit B delivers substantial new functionality—session-cookie web auth, a unified /post ingestion path, room-scoped thread views/routes (ThreadNav abstraction), and full router wiring—representing real, lasting feature/architecture work despite including some noise (a speculative plan2.md, Cargo.lock churn). Commit A is a small, focused set of UI polish fixes (vote-count tooltip, HUD unpin-via-POST instead of link, CSS/test tweaks) which is useful but narrow in scope and impact compared to B's structural additions.
B restores foundational multi-room web UI: session cookies + /login|/logout|/post, ThreadNav scoped to public vs private rooms with ACL checks, room index/thread/post/expand routes, compose forms, and home listing of granted rooms—real product surface. A only polishes existing garden pin/vote UX (vote-count badges, HUD unpin form, docs/CSS/tests), which is useful but narrower and dependent on prior structure.
Side B restores substantial web functionality by wiring browser session cookies, login/logout, room-aware thread routing, authenticated posting, and integrating these into the application's router, creating lasting infrastructure for the web UI. Side A improves the garden experience with pairwise vote counts, an unpin HUD action, styling, and tests, but these are incremental UI enhancements rather than foundational capabilities.
comparison · c_6f04dcb2e38c (tommy-mor) vs c_3ff71f7eaeda (tommy-mor)
Side A removes an entire legacy projection code path (dead GitDiscovery-based rendering), simplifies epoch/commit pages to a single Evidence-only contract, and rewrites tests to match the new schema — a clear architectural simplification reducing future maintenance burden. Side B is a useful but more incremental UI fix (vote-count badges, unpin-via-POST instead of link) bundled with theme CSS tweaks and a browser test, valuable but narrower in scope than A's structural cleanup.
A removes legacy GitDiscovery/Emission projection paths and makes Evidence envelopes the sole source for epoch/commit pages, tightening Emission required fields and tests—a lasting schema/design cleanup of core ledger honesty. B improves garden UX (vote counts on edges, HUD unpin via POST clear) with solid tests, but it is incremental product polish rather than foundational correctness.
Side A makes a substantive architectural change by removing legacy GitDiscovery projection paths and requiring Evidence-envelope-backed data throughout the epoch and commit pages, simplifying code, eliminating fallback logic, tightening the Emission schema, and updating tests accordingly. Side B adds useful UI improvements (vote counts, HUD unpin action, related styling, and tests), but these are feature enhancements rather than a foundational cleanup of the project's data model and evidence handling.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_597d3f736194 (tommy-mor)
Side B fixes genuine crashing bugs in test infrastructure: `str/split` called with a plain string instead of a regex (throws ClassCastException), and `.getInputStream`/`-1` misuse on HttpExchange (wrong API, breaks POST body reads), plus nil-safety for token/state — these were actually breaking the OAuth E2E flow entirely. Side A is mostly UI polish (vote-count badges, HUD unpin button) with reasonable but lower-stakes value, since it doesn't fix a broken core mechanism but refines an already-working feature.
A adds lasting product behavior: pairwise edge vote counts in the garden UI (with a real helper + unit test), HUD unpin via POST clear instead of a misleading item link, and browser coverage for that flow. B is valuable but narrower—surgical correctness fixes in OAuth/Reddit test mocks (split/API/null/state) that restore E2E auth; important infrastructure, less enduring app design than A.
Side B repairs broken OAuth test infrastructure by fixing query parsing (`str/split` regex), reading POST bodies from `getRequestBody`, handling missing state/token values safely, correcting redirect responses, and wrapping mock handlers to avoid crashes, directly restoring end-to-end authentication flows. Side A adds useful UI enhancements (pairwise vote counts, HUD unpin button, styling, and tests), but these are primarily feature and UX improvements rather than restoring critical project functionality.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_939729b4d9a6 (tommy-mor)
Side B introduces a real feature extension (typed $form:i32 holes, a new /vote page/route, redirect-after-vote support) with accompanying unit tests, representing genuine new functionality and a more general templating mechanism. Side A is a UI polish commit (vote counts on garden icons, unpin button behavior) that is useful but narrower in scope and mostly cosmetic/test-adjustment work, with less structural or reusable value than B's typed-hole and routing additions.
B lands lasting core design: typed `$form:i32` holes, RecordVote `next` navigation, vote route/CTA, and the compare slider/UI plumbing that the product builds on. A is valuable polish (HUD unpin vs false permalink, edge vote counts, regression tests) but refinements on existing garden-pin behavior rather than new foundational capability.
Side A delivers concrete product improvements: it adds pairwise vote counts to the garden UI with supporting logic and tests, changes the pinned-item HUD from a misleading permalink into a functional unpin action via POST /ui, updates CSS, and adds browser coverage for the new behavior. Side B mainly lays groundwork (new dependencies, typed form-hole substitution, routing/hooks, CSS/JS scaffolding) with only small visible behavior changes, and much of the apparent functionality depends on code not present in the patch.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_06fce70179bc (tommy-mor)
Side B implements a substantive architectural improvement: converting entity fetch from fire-and-forget to a proper SSE stream with typed FetchJobResult outcomes, oneshot completion signaling, richer tracing, and updated tests/client JS to consume the stream—this is a real feature/bugfix with lasting design value. Side A is a smaller UI polish commit (vote counts on garden rows, HUD unpin-via-POST instead of link) plus minor test additions, which is useful but more incremental and narrower in scope than B's protocol-level refactor.
B’s lasting value is the end-to-end fetch redesign: oneshot FetchJobResult from the Reddit worker, a dedicated fetch module, and SSE (fetching/complete/error) with client consumption so the UI can wait on real outcomes instead of fire-and-forget morph. A is solid but narrower—correct pin HUD unpin via set_garden_pin clear, pairwise vote counts on garden icons, plus tests/CSS—and does not change core async design the way B does.
Side B introduces a substantial architectural improvement by moving entity fetching from a synchronous JS-morph response to an SSE-based workflow, adding a dedicated fetch module, streaming progress/completion events, worker completion notifications via oneshot channels, and client-side SSE handling. Side A improves the garden UI with pairwise vote counts, HUD unpin behavior, styling, and tests, but these are localized UX enhancements rather than a broad infrastructure change.
comparison · c_3ff71f7eaeda (tommy-mor) vs c_9608dc0d38ab (tommy-mor)
Side B fixes a real concurrency bug: nested RwLock reads inside a match previously held a guard across further read/write calls, which could deadlock tokio's non-reentrant lock — a lasting correctness fix backed by a new integration test, plus corrects wrong test assertions (@user vs stored username) and hardens test harness timeouts to prevent flaky hangs. Side A is mostly UI polish (vote counts, HUD unpin button, CSS) which is useful but cosmetic and lower-stakes compared to a deadlock fix.
B fixes a real tokio RwLock deadlock in RoomCreate/RoomGrant by dropping the principal-verify guard before nested read/write awaits, plus an integration test and test harness hardening (server log redirection to avoid pipe deadlocks, HTTP timeouts). A is useful garden UX (vote-count badges, HUD unpin form, CSS, browser coverage) but is polish on an existing flow, not a core correctness fix.
Side B fixes a substantive concurrency bug by ensuring `RwLock` read guards are dropped before later `read().await`/`write().await` calls in RPC handlers, preventing potential deadlocks during room creation and grants. It also adds an integration test covering private room creation and improves test robustness with logging and HTTP timeouts, whereas Side A mainly enhances the garden UI (vote counts, HUD unpin button, styling) with supporting tests rather than addressing a core correctness issue.