comparison · c_326a64125966 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B is a substantive type-safety refactor that threads a CanonicalItemUrl newtype through pair selection, validation, and rank-change computation, eliminating repeated string-to-key conversions and reducing risk of mismatched string comparisons, plus adds Deref impls with a test. Side A is a trivial one-line UI tweak (conditionally omitting disabled=false) with no lasting architectural value.
Commit B is a substantive type-safety refactor: resolve_item now returns CanonicalItemUrl, call sites drop repeated CanonicalItemUrl(parse/clone) noise, pools/maps/HashSets use the newtype directly, and Deref is added on the URL wrappers—real lasting design cleanup across api/helpers, rpc, validate, and paths. Commit A only rewrites one button’s disabled attr as an @if/@else; a tiny local markup tweak with negligible ongoing impact.
Side B performs a substantial type-safety refactor by changing `resolve_item` to return `CanonicalItemUrl`, propagating canonical URL newtypes throughout validation, ranking, RPC, and connectivity code, and adding `Deref<Target=str>` implementations plus tests. This removes repeated string wrapping/parsing, reduces opportunities for mixing raw strings with canonical IDs, and improves API correctness, whereas Side A only rewrites conditional button rendering to emit a literal `disabled` attribute instead of a bound boolean.
comparison · c_c42f908efc44 (tommy-mor) vs c_64faa3bee86f (tommy-mor)
Side A performs a substantial type-safety refactor (introducing Deref for newtypes, threading CanonicalItemUrl through resolve_item/validate/rpc), reducing ad-hoc string keys and CanonicalItemUrl::parse calls, which lowers risk of subtle bugs across core ranking/validation logic. Side B is a focused UX improvement (auth form morphs in place instead of redirecting) that's useful but narrower in scope and touches less critical, more presentation-layer code.
A threads CanonicalItemUrl through resolve_item, validation HashSets, pair pools, connectivity stats, and rank-change maps, removing repeated String↔CanonicalItemUrl wrap/parse noise and adding Deref on href newtypes—core type-safety that sticks across the API. B only swaps auth choose-username redirects for HTML fragments plus a small poem JS morph path and CSS, a valuable but narrow UX tweak.
Side A replaces many raw `String` path usages with the `CanonicalItemUrl` type throughout validation, ranking, pair selection, and RPCs, changes `resolve_item` to return the typed value, and adds `Deref<str>` for URL newtypes to reduce conversions while improving type safety and API consistency. Side B improves the authentication flow by returning HTML fragments for inline form updates via the existing JS interceptor, but its impact is primarily user-interface behavior rather than a broad structural improvement to correctness and maintainability.
comparison · c_16438843de8f (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B is a genuine, coherent type-safety refactor that threads CanonicalItemUrl through resolve_item, rank change computation, pair selection, and validation, reducing string-based bugs and improving compile-time guarantees. Side A merely adds unintegrated scaffolding files (Dockerfile, fly.toml, event_log.rs, views.rs, deps.edn) that aren't wired into the codebase and appear to be dumped, disconnected infrastructure rather than a cohesive improvement.
A adds lasting product infrastructure: EventLog JSONL append/load, ViewStore persistence with async flush, plus Dockerfile and fly.toml that make the server deployable. B is a worthwhile type-safety refactor (Deref on URL newtypes, CanonicalItemUrl through resolve_item/validate/pair/rank paths) that removes stringly conversions, but it mostly reshapes existing code rather than introducing new capability.
Side B performs a substantive type-safety refactor by changing `resolve_item` to return `CanonicalItemUrl` instead of `String`, propagating strongly typed canonical URLs throughout ranking, validation, and RPC code, eliminating repeated parsing/wrapping and reducing opportunities for misuse. Side A adds useful infrastructure (Dockerfile, Fly deployment config, event log, and view persistence), but much of it is deployment/support code and new utilities, whereas B improves the core API design and correctness across many existing code paths with lasting architectural value.
comparison · c_97611919bf0b (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A introduces a real structural ItemId enum replacing the string-newtype CanonicalItemUrl, deleting the now-obsolete plan.md and propagating the new type consistently through reducer, ranking, RPC, and HTML modules with updated tests — a substantive architectural improvement toward correct identity modeling. Side B is a much smaller incremental cleanup (Deref impls, resolve_item returning CanonicalItemUrl, minor plumbing) that is useful but far less consequential and was effectively superseded by the deeper refactor in A.
A introduces the lasting ItemId structural type (new item_id/item_wire modules), removes CanonicalItemUrl, and migrates reducer maps, ranking, RPC, HTML, and tests to typed identity—the architectural end state. B only tightens intermediate CanonicalItemUrl/String plumbing and adds Deref on href newtypes, which is useful but incremental and largely superseded by A.
Side A introduces a new structural `ItemId` type with parsing, serialization, parent/display logic, separates wire normalization into `item_wire.rs`, and migrates reducer state, ranking, routing, HTML, RPC, and tests from `CanonicalItemUrl` to the new identity model. Side B mainly improves type usage around the existing `CanonicalItemUrl` (returning it from `resolve_item`, using it consistently in collections, and adding `Deref` for URL newtypes), which is a useful cleanup but does not deliver the deeper architectural change or broad migration implemented by Side A.
comparison · c_28dfd8015c8a (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B is a substantive type-safety refactor threading CanonicalItemUrl through resolve_item, pair selection, rank-change computation, and validation, eliminating repeated ad-hoc String/CanonicalItemUrl wrapping and adding Deref impls plus a new test — real reduction of bug surface across multiple files. Side A is a useful but tiny config simplification (one glob pattern replacing enumerated namespaces) with no code or test logic changes, offering less lasting engineering value despite solving a real discoverability problem.
B threads CanonicalItemUrl through resolve_item, validation, ranking, and pair RPC and adds Deref on href newtypes, removing repeated String wrap/parse noise and hardening the domain model across helpers, rpc, and validate. A only rewrites tests.edn to a single ns-pattern suite—useful auto-discovery hygiene, but a small config change with far less lasting design impact.
Side B makes a broad, lasting type-safety improvement by changing `resolve_item` to return `CanonicalItemUrl` instead of `String`, propagating that typed representation through validation, ranking, RPC handling, and connectivity logic while eliminating repeated parsing and string wrapping. Side A improves developer workflow by replacing manually enumerated Kaocha suites with a single auto-discovered `test\..+` suite, but this is a configuration convenience rather than a core design improvement.
comparison · c_cf0a514b261a (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B is a substantial type-safety refactor that threads CanonicalItemUrl through resolve_item, RPC handlers, and validation, eliminating repeated string-to-newtype conversions and reducing the chance of stringly-typed bugs across a large surface area, plus adding Deref impls for ergonomics. Side A is a tiny, low-risk cleanup removing dead code with a corresponding test fix, which is correct but narrow in scope and impact compared to B's broader architectural improvement.
B pushes CanonicalItemUrl through resolve_item, pools, validate, rank-change maps, and pair selection, dropping repeated String wrap/unwrap and CanonicalItemUrl::parse round-trips while adding Deref on href newtypes—real type-boundary cleanup with lasting API clarity. A only deletes a dead zero-ratio early-return already enforced at parse/handler and retargets one test; correct hygiene, but far smaller enduring design impact.
Side B performs a broad but coherent type-safety refactor by changing `resolve_item` to return `CanonicalItemUrl`, propagating canonical URL types through validation, ranking, RPCs, and connectivity logic, and adding `Deref<str>` support to URL newtypes to reduce string conversions. Side A removes a redundant zero-ratio guard and updates the corresponding test to reflect that zero-weight edges are skipped later while items are still registered, which is a comparatively small cleanup with limited architectural impact.
comparison · c_1c1c8e7a2de8 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A implements an actual end-to-end feature (room create CLI subcommand, RPC, docs, tests) and simplifies the data model by removing an unused/redundant visibility concept, which is a real, shippable improvement. Side B is a broad but mechanical refactor (String -> CanonicalItemUrl newtype, Deref impls) that touches many call sites without adding new capability or fixing a concrete bug, offering type-safety benefits but less direct user-facing value.
A lands a real product path (CLI `room create` + docs) and a lasting domain simplification—dropping ThreadVisibility/RoomState so rooms are a HashSet of private ids and RoomCreate no longer takes visibility—plus matching RPC/reducer/test updates. B is a worthwhile but narrower type-hygiene refactor (Deref on URL newtypes, CanonicalItemUrl through resolve_item/pair/validate) that mainly removes intermediate String maps without changing user-facing behavior.
Side A adds a user-facing `room create` CLI command end-to-end, wiring it through the RPC, bearer authentication, documentation, and tests, while also simplifying the room model by removing the unused visibility field and replacing the room registry with a `HashSet` of room IDs. Side B is a solid internal refactor that strengthens type usage by returning `CanonicalItemUrl` from `resolve_item` and propagating typed URLs throughout ranking and validation code, but it is primarily a maintainability improvement rather than introducing new project capability.
comparison · c_ebc883667d61 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A is pure file reorganization (splitting a monolith into modules) with no behavioral change, which has value but is mechanical churn. Side B introduces a real type-safety improvement by threading CanonicalItemUrl through resolve_item, validate, and rank computations instead of raw strings, reducing stringly-typed bugs, plus adds Deref impls that reduce boilerplate call sites—this is a more substantive, lasting design improvement to the codebase's type system.
B tightens core path typing end-to-end (resolve_item → CanonicalItemUrl, typed pools/maps in validate/rank/pair RPC, Deref on href newtypes), removing repeated String↔CanonicalItemUrl glue and hardening the API model. A’s lasting piece is real but smaller: deleting leftover html/forum.rs so forum/ is the sole module root; most of the huge diff is relocated split-module code rather than new behavior.
Side B makes a substantive type-safety refactor by changing `resolve_item` to return `CanonicalItemUrl`, propagating canonical path types through validation, ranking, pair selection, and RPC code, and adding `Deref<Target=str>` plus `from_stored` usage to reduce string conversions and parsing errors. Side A primarily removes the duplicate `server/src/html/forum.rs` and establishes `forum/mod.rs` as the sole module root—a useful structural cleanup that resolves module ambiguity, but it largely reorganizes existing code rather than strengthening core behavior.
comparison · c_bc8c17a00ed7 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B is a substantive type-safety refactor that threads CanonicalItemUrl through resolve_item, validation, scope-rank computation, and pair selection, eliminating repeated string-to-newtype conversions and reducing risk of key-mismatch bugs, backed by real call-site updates across multiple files. Side A is a small, focused bugfix (skip pinned Reddit posts) with a test, which is valuable but narrower in scope and impact than B's broader structural improvement.
B threads CanonicalItemUrl through resolve_item, validation, pair/rank RPCs, and connectivity helpers and adds Deref on href newtypes, cutting repeated String↔canonical wrapping across the API core—a lasting type-design improvement. A is a correct, tested Reddit importer tweak (skip stickied/pinned children) but is a narrow edge-case filter with local scope only.
Side B makes a broad, lasting type-safety refactor by changing `resolve_item` to return `CanonicalItemUrl` instead of `String`, propagating canonical URL types through validation, ranking, RPC logic, connectivity calculations, and pair selection, while also adding `Deref<str>` implementations to reduce string conversions. Side A fixes a specific importer behavior by skipping stickied/pinned Reddit posts and adds a focused regression test, but its impact is limited to one import path compared with B's architectural improvement across many APIs.
comparison · c_66eb04076a98 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
B is a broader type-safety refactor that removes stringly-typed item paths in favor of CanonicalItemUrl/newtype Deref impls, reducing risk of mismatched string keys across resolve_item, connectivity stats, and RPC pairing logic—real structural improvement with test coverage. A is a smaller, well-tested fix improving color-gradient correctness for rank rows, which is valuable but narrower in scope and impact than B's cross-cutting type refactor.
A replaces ordinal/list-position gradient coloring with min–max normalization of actual vote mass (score_gradient_t + per-group min/max), a precise behavioral fix that keeps similar scores visually close and is backed by targeted tests; B is a worthwhile but largely mechanical type-propagation refactor (Deref on URL newtypes, CanonicalItemUrl through resolve_item/pools/maps) that removes String churn without changing user-visible behavior or fixing a defect.
Side B performs a broad but coherent type-safety refactor by making `resolve_item` return `CanonicalItemUrl` instead of `String`, propagating canonical URL types through validation, ranking, RPC, and pair selection, and eliminating repeated parsing/wrapping logic while adding `Deref<str>` support for URL newtypes. Side A improves UI behavior by changing row coloring from list position to score-based min–max normalization with solid tests, but its impact is limited to presentation whereas Side B strengthens core API correctness and maintainability across many code paths.
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_4a5c84c0a37b (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B performs a substantive type-safety refactor (resolve_item returns CanonicalItemUrl, Deref newtype impls, typed pools/keys throughout rpc.rs and validate.rs), reducing stringly-typed bugs across a broad surface. Side A is a smaller, useful UI/test fix (display_path in hrefs plus a strengthened browser test) but touches far less of the codebase and has narrower long-term impact than B's type-system hardening.
A fixes real href behavior (encode display_path for left/right/pool instead of full storage URLs) and replaces a shallow 15-iteration smoke loop with a full C(10,2)=45 pairwise vote plus GetGardenRank assertions on connectivity and a→j order. B is a worthwhile CanonicalItemUrl/Deref type-threading refactor that removes String wrap/unwrap noise across RPC/validate, but it does not add user-visible correctness or stronger behavioral guarantees.
Side A fixes user-facing URL generation by using `display_path()` for vote links instead of exposing stored canonical `https://slug.social/...` IDs, aligning hrefs with the displayed DSL paths. It also substantially strengthens the browser test by exercising all 45 pairwise votes in a 10-item pool and asserting the final ranking through `GetGardenRank`, providing end-to-end verification of ranking correctness. Side B is a useful type-safety refactor (returning `CanonicalItemUrl`, propagating typed paths, and adding `Deref`), but it is largely structural and does not introduce an equally direct functional improvement or behavioral guarantee.
comparison · c_c42f908efc44 (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
Side A performs a genuine type-safety refactor (newtype Deref impls, threading CanonicalItemUrl through resolve_item, rank-change computation, and pair RPC) that reduces stringly-typed bugs and clarifies invariants across core server logic. Side B is a legitimate but narrow UI feature (clickable unpin icon) plus CSS/test churn, which is useful but smaller in architectural impact than A's cross-cutting type correctness improvements.
A threads CanonicalItemUrl through resolve_item, validation HashSets, scope-rank maps, pair pools, and connectivity stats while adding Deref on href newtypes, replacing repeated String/parse wrapping with typed APIs across the core server path. B only turns a static pin glyph into an unpin form in child rankings (plus CSS/test updates)—real UX polish, but a narrow UI hook versus A’s lasting type-boundary cleanup.
Side A performs a broad, type-safe refactor by changing `resolve_item` to return `CanonicalItemUrl`, propagating canonical URL types through validation, ranking, pair selection, and connectivity logic, and adding `Deref<Target=str>` for URL newtypes to reduce conversions. This removes repeated parsing/wrapping (`CanonicalItemUrl(it.clone())`, `parse(...)`) and makes canonical IDs first-class across the API, whereas Side B is a localized UI enhancement that makes pinned child-group icons clickable to unpin and adds corresponding browser tests and CSS.
comparison · c_8dc1a8119370 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A removes an unreliable, ~1800-line keystroke-parsing state machine (plus its debounce/race-mitigation JS and a whole Playwright race test) and replaces it with a much simpler, correct paste-and-go flow, eliminating a real class of bugs and maintenance burden. Side B is a solid type-safety refactor (Deref impls, CanonicalItemUrl propagation) that reduces stringly-typed bugs, but it's incremental internal cleanup rather than fixing a demonstrably broken user-facing feature.
A removes an ~1800-line unreliable keystroke graph parser, parser_action, race-handling JS, and Playwright race test, replacing them with a small correct paste-and-go URL parser and redirect that still covers real Reddit paths. B only threads CanonicalItemUrl and adds Deref on href newtypes—useful type hygiene without changing product behavior—so the design simplification and bug-class removal in A carry more lasting value.
Side B strengthens core data modeling by changing `resolve_item` to return `CanonicalItemUrl`, propagating that typed identifier through validation, ranking, pair selection, and scope-change computation, eliminating repeated parse/wrap conversions and reducing stringly-typed APIs. Side A replaces a rich autocomplete/graph parser with a much simpler paste-and-go flow and deletes substantial parser logic and tests, which simplifies maintenance but also removes existing capabilities rather than improving the underlying architecture.
comparison · c_c42f908efc44 (tommy-mor) vs c_c25451965a7f (tommy-mor)
Side A performs a real type-safety refactor (introducing Deref for newtypes, threading CanonicalItemUrl through resolve_item, validation, rank computation, and pair selection), removing ad-hoc string/CanonicalItemUrl conversions and reducing risk of key-mismatch bugs across the ranking pipeline. Side B is a legitimate but narrower fix consolidating hostname/base-URL logic into a single util function and adjusting CI deploy branch, which is useful but smaller in scope and lasting architectural impact compared to A's cross-cutting type unification.
A systematically threads CanonicalItemUrl through resolve_item, validation HashSets, pair/pool selection, connectivity stats, and scope rank maps while adding Deref on the href newtypes, replacing repeated String/Canonical parse-wrap-clone noise with a lasting type-safe design. B correctly centralizes get-base-url/HOSTNAME and window.location.origin (plus staging deploy trigger) to fix hardcoded OAuth/redirect hosts, but that is narrower env-glue compared with A’s core path model cleanup.
Side A strengthens the project's type safety by changing `resolve_item` to return `CanonicalItemUrl` instead of `String`, propagating canonical URL types through validation, ranking, pair selection, and connectivity logic, and adding `Deref<Target=str>` for URL newtypes to reduce conversions. Side B fixes deployment and redirect behavior by centralizing base URL generation around `HOSTNAME`/`window.location.origin` and updating the staging deployment workflow, but its impact is narrower than A's architectural improvement that reduces future misuse of raw strings across many APIs.
comparison · c_0c466eea1ed4 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B is a substantive type-safety refactor that replaces error-prone String/raw-string item ids with a proper CanonicalItemUrl newtype threaded through validation, RPC pairing, and rank-change computation, reducing a class of stringly-typed bugs and improving compile-time guarantees across core server logic. Side A adds a useful but peripheral dev-only CLI tool (sorterc) that wraps existing server logic for offline linting/compiling, which is valuable tooling but doesn't change or harden the core system's correctness or design the way B's refactor does.
A adds a real offline compile/scan path (server offline module, tests, workspace binary, docs) that reuses production validation and reducer logic for durable dev/CI workflows. B is a worthwhile type-safety cleanup (CanonicalItemUrl through resolve_item, Deref on href newtypes, fewer String round-trips) but remains mostly mechanical propagation without new behavior.
Side A adds a substantial new offline capability: a reusable server `offline` module plus a new `sorterc` workspace binary that compiles `.sorter` files, replays reducer state, scans `events.jsonl` for corrupt or malformed ingests, includes tests, and documents the workflow. Side B is primarily a type-safety refactor that replaces `String` paths with canonical URL newtypes and `Deref` implementations across existing code, improving clarity and reducing conversions but largely preserving existing behavior rather than adding new project functionality.
comparison · c_cd965c070df3 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A fixes a real bug (Reddit children not attaching correctly and unranked labels showing raw slugs instead of titles), with corresponding test coverage validating the fix. Side B is a broad but mechanical type-refactor (String -> CanonicalItemUrl, adding Deref impls) that improves type safety but doesn't fix a user-visible bug, and includes some risky churn (e.g., using ranked[i].item.as_str() while also pushing pairs, mixed use of parse vs direct newtype).
A fixes real product bugs: Reddit listing children no longer go through ensure_path (apply_entity_under_parent avoids /comments/ path pollution) and unranked items show stored titles via child_label, with expanded SSE/children integration tests. B is a solid type-hygiene refactor (CanonicalItemUrl through resolve_item, Deref on URL newtypes) that reduces String round-trips but adds no equivalent behavioral fix.
Side A fixes a concrete functional bug in Reddit child imports by introducing `apply_entity_under_parent` to attach imported children directly without `ensure_path` creating unwanted `/comments/...` hierarchy, and it updates the ranking panel to display imported child titles instead of raw IDs. It also adds integration tests covering SSE updates and Reddit child fetching, whereas Side B is primarily a broad type-safety/refactoring pass (moving from `String` to `CanonicalItemUrl`, adding `Deref`, and API signature changes) with little visible behavioral improvement.
comparison · c_410d9361a866 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
B performs a genuine type-safety refactor, replacing loosely-typed String item paths with CanonicalItemUrl throughout the RPC/validation layer and adding Deref impls to reduce boilerplate, which reduces bug surface and clarifies invariants across the codebase. A adds a real user-facing feature (reddit post rendering with images/links) with decent test coverage, but it's more localized and additive rather than improving the correctness/maintainability of existing core logic; B's changes, while less flashy, touch more fundamental plumbing that lowers future defect risk.
A adds lasting product capability: EntityData image_url/link_url, Reddit URL/image parsing with a fixture test, a dedicated render/reddit module (detail cards and list thumbs), and CSS—real domain behavior. B is worthwhile type hygiene (Deref on href newtypes, resolve_item → CanonicalItemUrl, less String wrapping) but mostly mechanical plumbing across API paths without new behavior or bugfixes.
Side A adds substantial end-user functionality by introducing Reddit-specific rendering (thumbnails in ranking lists, full post cards), extending EntityData with image/link metadata, implementing Reddit parsing helpers for those fields, and adding a regression test with a fixture. Side B is primarily a type-safety refactor that changes many APIs from String to CanonicalItemUrl and adds Deref implementations, improving code clarity but with little visible behavioral change compared with A's new capabilities.
comparison · c_8c6a5e2e4a54 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A delivers a substantial, working feature (private room UI, session cookies, web posting form, room-scoped routing) that materially extends the application's capabilities, despite including some noisy/unpolished artifacts (plan2.md AI chat log). Side B is a solid internal refactor (newtype deref, canonical item plumbing) improving type-safety and reducing stringly-typed code, but it's lower-impact churn with no new user-facing capability, so it contributes less lasting value despite being cleaner.
Commit A ships lasting product surface: session cookies and web login/logout, private room pages/threads with ACL checks, compose/post forms via rpc_post_with_bearer, and ThreadNav so public and room UIs share one path model. Commit B is a worthwhile type-safety refactor (CanonicalItemUrl through resolve_item/rank/pair paths and Deref on href newtypes) that removes String churn but does not add user-facing capability.
Side A delivers substantial end-user functionality by wiring the web UI back together: it adds browser login/logout with session cookies, authenticated web posting, room-aware thread pages, routing, and reusable helpers for principal resolution, enabling the application to be used through the browser. Side B is a solid internal refactor that strengthens type safety by propagating `CanonicalItemUrl` and adding `Deref` implementations, but it mostly restructures existing code without adding comparable user-visible capability.
comparison · c_c42f908efc44 (tommy-mor) vs c_597d3f736194 (tommy-mor)
Side B fixes real crashing bugs in test infrastructure (wrong str/split arity, wrong HttpExchange method calls, unguarded nil derefs, missing exception handling causing hangs) that were actually breaking E2E auth test runs. Side A is a mechanical refactor introducing Deref newtypes and threading CanonicalItemUrl through call sites, which is reasonable cleanup but lower-stakes than fixing a broken test harness that blocks CI signal.
A threads CanonicalItemUrl through resolve_item, validate, pair selection, and rank-change maps while adding Deref on the href newtypes, removing repeated String↔canonical wrapping across production API paths. B only repairs test OAuth mocks (request body API, split regex, null state/token, redirect length) and selector helpers so Playwright login works again—necessary but localized to test support rather than core domain types.
Side A makes a broad, lasting type-safety refactor by changing `resolve_item` to return `CanonicalItemUrl`, propagating canonical URL newtypes through validation, ranking, RPCs, and connectivity logic, and adding `Deref<Target=str>` implementations to reduce string conversions. Side B fixes important test infrastructure for OAuth E2E flows (correct request-body reading, safer query/token parsing, redirect handling, and mock error handling), but those improvements are confined to test mocks rather than the project's core APIs and data model.
comparison · c_c124c217f89c (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A implements a substantial new feature: a background Reddit worker with OAuth token handling, rate-limit/backoff logic, JSON parsing for subreddits/posts, and integration into the browse route and AppState, complete with unit tests. Side B is a real but narrower type-safety refactor (String -> CanonicalItemUrl, adding Deref impls) that reduces stringly-typed code and removes redundant parsing, which is valuable but lower-impact than shipping a working external-data integration.
A delivers a complete, production-shaped Reddit import path (background broker, OAuth, rate-limit/backoff/dedup, JSON parsers, UI trigger, and wiring into AppState) that adds real external capability. B is a worthwhile type-hygiene refactor (Deref on URL newtypes and threading CanonicalItemUrl through resolve_item/pair/rank helpers) but only removes string churn with no new behavior.
Side A adds substantial new functionality: an asynchronous Reddit import pipeline with a background worker, OAuth support, rate-limit handling, JSON parsing into project entities, and integration that triggers fetches when Reddit items are added or browsed. Side B is a useful type-safety refactor that replaces many String usages with CanonicalItemUrl and adds Deref implementations, but it largely restructures existing code rather than introducing new project capabilities or fixing a significant behavioral issue.
comparison · c_14dd365ffe22 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B strengthens type safety by threading CanonicalItemUrl through resolve_item, scope-rank computation, and pair selection, and adds Deref impls for href newtypes—reducing stringly-typed bugs and repeated CanonicalItemUrl::parse calls across the codebase. Side A is a reasonable feature swap (dropping theming for /~/ browse URLs) with tests, but it trades one feature for another rather than improving correctness or maintainability, and includes wholesale deletion of CSS/theme code that was working.
A introduces a durable browse URL model (`ItemId::browse_href` / `from_browse_uri`, `/~/*` routing) and removes the theme cookie/CSS stack with matching integration tests, which changes how the app is navigated long-term. B is a worthwhile type-safety refactor (Deref on href newtypes, `resolve_item` → `CanonicalItemUrl`, fewer String re-wraps) but is mostly internal plumbing without new behavior or user-facing design.
Side A introduces a new canonical browse URL scheme (`/~/...`), centralizes link generation with `ItemId::browse_href`, adds parsing helpers and routing for path-based browsing, updates redirects, and includes integration tests, creating a lasting user-facing navigation improvement while removing obsolete theme infrastructure. Side B improves type safety by propagating `CanonicalItemUrl` through APIs and eliminating many string conversions, but it is primarily an internal refactor with limited behavioral change compared with A's new routing and URL model.
comparison · c_477013996fa5 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B tightens type-safety across the API layer by threading CanonicalItemUrl through resolve_item, pair-selection, connectivity stats, and rank-change computation, eliminating repeated string-based parse/allocate round-trips and the risk of stringly-typed mismatches. Side A is a solid UI/UX feature (fullscreen compare page, sorted edge history, morph on post) but is more localized and cosmetic (CSS, markup, sort order) compared to B's structural correctness improvement spanning multiple modules and reducing redundant parsing.
A completes real vote-compare behavior: page-left–oriented edge ratios and strength sorting, fullscreen chromeless layout, and post-success JS that actually morphs the new ingest card plus edge history, with unit and browser test updates. B is a worthwhile type-safety refactor (CanonicalItemUrl through resolve_item/pools and Deref on href newtypes) that removes String churn, but it is mostly mechanical propagation without user-facing or bugfix substance.
Side B strengthens the project's type safety by changing `resolve_item` to return `CanonicalItemUrl` instead of raw `String`, propagating canonical URL types through validation, ranking, pair selection, and RPC code, and adding `Deref<str>` implementations to reduce string conversions. Side A delivers meaningful UI improvements (fullscreen compare page, live preview morph, improved vote history ordering, and tests), but much of it is presentation-oriented, whereas B's refactor reduces incorrect string handling across core APIs and provides a more durable internal design.
comparison · c_57453fc5c6c0 (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side B tightens type safety by threading CanonicalItemUrl through resolve_item, validate, and rpc pair/rank logic instead of ad-hoc String/CanonicalItemUrl round-tripping, reducing a class of stringly-typed bugs across multiple call sites. Side A is a well-tested but purely additive UI feature (a copy-to-clipboard button) with no structural improvement to existing code, while Side B's refactor improves correctness and maintainability of core ranking/pairing paths that many features depend on.
A ships a complete, user-facing capability (CopyGardenRank + markdown formatting, UI affordances, integration/browser tests) that extends an existing pattern in a durable way. B is a worthwhile type-safety refactor (CanonicalItemUrl through resolve_item/pools, Deref on href newtypes) that cleans call sites without changing behavior, so it adds less product value than the feature.
Side B strengthens core type safety by changing `resolve_item` to return `CanonicalItemUrl` instead of raw `String`, propagating canonical path types through validation, ranking, pair selection, and RPC code while reducing repeated parsing and conversions. It also adds `Deref<Target=str>` for URL/path newtypes and updates APIs to use typed keys directly, whereas Side A primarily introduces a user-facing clipboard feature (`CopyGardenRank`) with new UI actions and tests but does not improve the underlying architecture as broadly.
comparison · c_c42f908efc44 (tommy-mor) vs c_6f04dcb2e38c (tommy-mor)
Side B removes dead legacy-projection code paths (dual code for GitDiscovery vs Evidence envelopes), simplifies epoch/commit detail pages to a single source of truth, and updates tests/schema accordingly, reducing long-term maintenance burden. Side A is a solid internal refactor (newtype Deref, CanonicalItemUrl threading) that improves type safety but is more mechanical churn with less architectural simplification than B's removal of an entire legacy compatibility layer.
B removes legacy GitDiscovery projection paths so epoch/commit UI and APIs only surface real Evidence envelopes, tightens Emission required fields, and updates tests—an enduring correctness boundary with intentional ledger impact. A is valuable type plumbing (Deref on href newtypes, CanonicalItemUrl through resolve_item/validate/RPC) that cuts string wrap/unwrap noise, but it mostly refines an already-working model rather than changing what the system of record is allowed to claim.
Side A strengthens the project's type safety by changing `resolve_item` to return `CanonicalItemUrl`, propagating canonical URL types through ranking, validation, connectivity, and pair-selection code, and adding `Deref<Target=str>` for URL newtypes to reduce string conversions. Side B removes legacy GitDiscovery projection paths and requires Evidence-only data for epoch/commit pages, simplifying the codebase but intentionally dropping backward compatibility and mainly affecting presentation and historical data handling.
comparison · c_9608dc0d38ab (tommy-mor) vs c_c42f908efc44 (tommy-mor)
Side A fixes a real, concrete bug: nested RwLock reads across match arms that would deadlock the RoomCreate/RoomGrant RPC paths (tokio::sync::RwLock is not reentrant), and backs it with a new integration test plus fixes to flaky/deadlock-prone test infra (log-file redirection, HTTP timeouts) and incorrect test assertions. Side B is a broad but mostly mechanical refactor (renaming from_storage_str->from_stored, threading CanonicalItemUrl/newtype Deref impls through many call sites) that improves type-safety but doesn't fix an active defect, making it closer to structural churn than a critical correctness fix.
A fixes real tokio RwLock deadlocks by scoping verify/cap/user-exists guards so nested read/write cannot hold a non-reentrant guard across the match, and backs that with a room-create integration test plus test harness fixes (log-file piping, HTTP timeouts) that stop false hangs. B is a solid type-safety refactor (Deref on URL newtypes, CanonicalItemUrl through resolve_item/pools/validate) that removes string wrap/clone noise but does not correct broken runtime behavior.
Side A fixes a concrete concurrency bug by shortening the lifetime of `state.reduced.read().await` guards before later `read()`/`write()` operations, explicitly preventing Tokio `RwLock` self-deadlocks in `RoomCreate` and `RoomGrant`, and adds an integration test covering private room creation. Side B is largely a type-safety refactor that replaces many `String` usages with `CanonicalItemUrl` and adds `Deref` implementations, improving API cleanliness but with less direct impact on runtime correctness than the deadlock fix.