comparison · c_55f1cdf12e22 (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
Commit A introduces a substantial new feature set spanning the CLI, server API, authentication flow, RPC layer, state management, reducer, shared types, routing, and integration tests. It implements shareable room invite links with redemption during OAuth, room auditing, multi-capability grants, new RPC commands and responses, thread timeline support, new routes, state structures, and comprehensive end-to-end tests. Although some event types appear only partially integrated, the overall change is a large architectural addition. Commit B is a focused usability improvement that makes pinned icons in ranked child groups clickable for unpinning, updates styling, threads a new parameter through rendering, and extends browser tests. It is a valuable UX enhancement but far smaller in scope and impact than the broad invitation and room management system introduced in Commit A.
Commit A introduces a full invite system end-to-end: new RPC commands, server-side state and redemption logic, auth flow integration, reducer updates, timeline integration, CLI support, and comprehensive tests. It significantly expands core functionality. Commit B is a focused UI improvement making an existing pin icon clickable to unpin, with minor rendering and CSS changes plus test updates. The scope and impact of A are far greater.
Side A introduces a full invite system end-to-end: new RPC commands (RoomMintInvite, RoomAudit), server routes (/join/:token), OAuth redemption flow integration, reducer state extensions, new event types, CLI commands, timeline merging, and comprehensive integration tests. It significantly expands backend capabilities, data models, and test coverage. Side B is a focused UI improvement making pin icons clickable to unpin, with corresponding CSS and browser test updates. While useful, it is comparatively small in scope and impact.
comparison · c_7ec4b410de02 (tommy-mor) vs c_66eb04076a98 (tommy-mor)
Commit A delivers a user-facing functional improvement by making pinned child-group icons clickable to unpin, wiring the existing POST flow into an additional UI surface, updating rendering, styling, and adding an end-to-end browser test that verifies the behavior across multiple navigation scenarios. It affects several components and improves usability. Commit B is a solid refinement that changes rank-row coloring from list-position-based to score-range-based normalization, with a clean helper function and good unit test coverage, but it is primarily a visualization improvement rather than adding new interaction capability. Both are valuable, but A has the broader product impact and implementation scope.
Side A introduces a new user-facing capability (unpinning directly from ranked child groups), wiring it through UI, server rendering, form handling, CSS, and end-to-end browser tests. It meaningfully expands interaction flow and consistency with existing pin controls. Side B refines visual encoding of rank rows with better normalization and solid tests, but it’s a contained presentation improvement rather than new functionality.
Commit A delivers a user-facing feature that enables unpinning directly from ranked child group rows, integrating backend rendering changes, form wiring, CSS updates across themes, and expanded end-to-end browser tests. It meaningfully extends interaction capabilities and modifies multiple layers of the stack. Commit B improves visual ranking fidelity with a better gradient normalization algorithm and solid unit tests, but its scope is confined to styling logic within a single module. Overall, A represents a broader and more impactful contribution.
comparison · c_55f1cdf12e22 (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
Side A implements a substantial new capability across the system: shareable room invites with OAuth redemption, room auditing, multi-capability grants, new RPCs/CLI commands, server routes, state handling, reducer updates, API/type changes, and integration tests. Side B is a focused UI improvement that makes existing pin icons in ranked child groups clickable to unpin, with corresponding CSS and browser test updates, but it is a relatively small usability enhancement compared with the new end-to-end functionality in Side A.
Side A introduces a full invite system end-to-end (RPC minting, auth redemption flow, state management, reducer updates, CLI commands, and integration tests), plus expands thread modeling with system items, while Side B only makes an existing pin icon clickable and adjusts CSS/tests. The former adds new core capabilities and data flows; the latter is a localized UI improvement.
Side A introduces a full invite system (RoomMintInvite, /join/:token flow, redemption applying GrantAdded events), RoomAudit RPC, timeline merging with ThreadItem::System, reducer support for invites, and comprehensive integration tests (test/invites.bb), significantly expanding core auth and room capabilities. Side B is a focused UI enhancement making ranked child group pin icons clickable to unpin, with CSS tweaks and a browser test, but does not alter core domain logic.
Side A implements a full invite system feature spanning event sourcing, RPC endpoints, HTTP routes, CLI commands, reducer state, and integration tests—substantial, non-trivial, lasting functionality. Side B is a focused UI polish fix (making pin icons clickable to unpin) which is useful but much smaller in scope, touching only templating/CSS and browser test updates.
Commit A lands a full invite-access feature (mint/redeem RPCs, /join OAuth path, multi-cap grants, RoomAudit, reducer/timeline/types/CLI, and invites integration tests), which permanently expands core product capability. Commit B only turns an existing ranked-child pin glyph into a form that posts the already-supported set_garden_pin clear action, plus CSS/test tweaks—a small local UX affordance.
comparison · c_7ec4b410de02 (tommy-mor) vs c_66eb04076a98 (tommy-mor)
Side A adds a concrete user-facing capability by making pinned child-group icons submit the existing set_garden_pin clear flow, wiring the required navigation path through rendering, updating styles for the new button state, and adding an end-to-end browser test covering unpinning from the ranked list and its effects. Side B improves visual encoding by changing row coloring from list position to score-based min–max normalization with unit tests, but it is primarily a presentation refinement rather than a functional capability or bug fix.
A converts a non-interactive pinned icon into a working unpin control by wiring a POST /ui RPC (including new next_path plumbing) and adds an end-to-end browser test verifying the behavior, delivering real functionality. B only changes row coloring logic from ordinal-based to score-based gradients with unit tests, which is a visual refinement rather than a core capability.
Side A turns a static pinned icon into a functional POST form that reuses the existing /ui set_garden_pin flow, adds the necessary next_path plumbing, updates styles, and extends the browser test to verify unpinning from ranked child lists—clearly fixing a real UX gap. Side B improves visual semantics by switching from ordinal-based to min–max score-based gradients with solid unit tests, but it’s a presentation refinement rather than enabling new functionality.
A adds a real missing interaction (unpin directly from ranked child rows via the same POST /ui flow) with corresponding CSS states and an extended browser test covering the new UX path, delivering tangible user-facing functionality. B is a reasonable visual tweak (min-max score gradient) with good unit tests, but it's a smaller, purely cosmetic refinement affecting only color mapping, with lower functional impact than A's new capability.
B replaces ordinal-position coloring with min–max score normalization and documents the dilution issue, so rank colors carry lasting semantic meaning backed by focused unit tests. A only adds unpin parity on an already-pinned glyph (form + CSS + browser coverage), useful UX consistency but less foundational than correcting how rank mass is visualized.
comparison · c_b00c261f06c2 (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
B ships a concrete, testable feature (clickable unpin from ranked child groups) with a real backend/UI flow change plus an expanded browser test covering the new interaction end-to-end. A is a legitimate bugfix with good unit tests, but it also introduces a large CSS regression (fixed 3-way slider gradient with hardcoded 50% midpoints that breaks the actual slider value display, contradicting its own JS which still sets --vote-slider-pct dynamically), making its visual fix partially inconsistent, whereas B's change is self-contained and verified more thoroughly.
A fixes real ranking/vote-display bugs (per-group gradient ordinals instead of global offsets; center-anchored winner fill and slider polarity matching the HUD) and locks them in with polarity/unit tests, so the core compare UX stays correct. B only wires an existing unpin RPC onto ranked-child pin icons plus browser coverage—useful consistency, but a smaller localized feature than A’s correctness work.
Side A fixes a correctness issue in vote/ranking presentation by changing rank gradient calculation to be per-group instead of global, aligns vote-history slider polarity with the live HUD, and adds focused unit tests covering the orientation and ranking invariants. Side B adds a useful UI capability by making pinned icons in ranked child groups clickable to unpin and verifies it with an end-to-end browser test, but it is a narrower feature enhancement rather than a broader correctness fix affecting core vote visualization and ranking behavior.
comparison · c_4a5c84c0a37b (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
B delivers a genuine user-facing feature (clickable unpin from ranked child groups) with corresponding CSS and an expanded browser test covering the new interaction, providing real functional value. A is a solid bugfix (display_path in hrefs) plus a much stronger, more rigorous test rewrite, but it's a narrower display-string fix versus B's added interactive capability.
A fixes real href correctness (encode display_path short forms instead of storage URLs in vote_compare/pool links) and turns the pool browser test into a full C(10,2)=45-pair exhaustive vote plus GetGardenRank assertion of a→j ranking—durable coverage of core ranking behavior. B is a useful but narrower UX polish: wire the existing set_garden_pin clear flow to ranked-child pin icons with CSS/test updates, without the same foundational correctness or regression weight.
Side A changes vote URL generation to use `display_path()` instead of storage URLs for left/right/pool parameters, aligning links with the user-facing path format, and substantially strengthens the browser test by exercising all 45 pairwise votes and verifying the final `GetGardenRank` ordering. Side B adds a useful UI improvement by making pinned icons in ranked child lists submit the existing unpin flow and covers it with browser tests, but its impact is narrower and primarily affects one interaction path.
comparison · c_7ec4b410de02 (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Side A ships a real, working feature: it wires unpin functionality into the ranked child group list, updates CSS for the new interactive states, and extends a browser test to actually exercise the new flow end-to-end. Side B is a large planning document plus an unused/unreferenced RouteContext scaffold (no call sites migrated, no tests), representing intent rather than delivered, tested functionality.
A ships a real UX fix: pinned ranked-child rows become submit buttons using the existing set_garden_pin clear flow, with CSS and an extended browser test covering unpin from the list. B is mostly a temporary plan.md plus a thin RouteContext wrapper around ThreadNav with no callers migrated, so it adds little lasting product behavior yet.
Side A implements a user-visible functional improvement by making pinned child-group icons submit the existing POST /ui unpin action, threads the redirect path through rendering, updates styling, and adds comprehensive browser tests covering unpinning from the ranked list and HUD behavior. Side B primarily adds a planning document plus a thin RouteContext wrapper export without migrating call sites or changing behavior, so its lasting impact is much smaller despite outlining future work.
comparison · c_bc8c17a00ed7 (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
Side B implements a real, non-trivial UI/UX feature (clickable unpin from ranked child groups) with coordinated changes across markup, CSS themes, and an updated browser test covering the new flow, delivering tangible user-facing value. Side A is a small, well-tested bugfix (skipping pinned Reddit posts) which is useful but narrower in scope and impact than B's cross-cutting feature work.
A is a precise ingest correctness fix: it filters stickied/pinned Reddit listing children via a small helper and locks the behavior with a unit test, so meta posts never enter stored data. B improves UX by wiring an existing set_garden_pin clear path into ranked-child pin glyphs (plus CSS and browser coverage), but that is incremental UI consistency on an already-supported flow rather than a foundational data-quality change.
Side B adds a meaningful user-facing capability by turning the ranked child-group pin indicator into a working unpin control that reuses the existing POST /ui set_garden_pin flow, updates rendering to preserve navigation, adjusts styling, and extends browser integration tests to verify the full interaction. Side A is a solid import bugfix that filters stickied/pinned Reddit posts during subreddit listing import and adds unit tests, but its scope is narrower than the end-to-end UI functionality and coverage added in Side B.
comparison · c_7ec4b410de02 (tommy-mor) vs c_978e283f2229 (tommy-mor)
Side B restructures the CLI's forum command (list/show/post subcommands), fixes a real bug (removing double-escaping via escape_xml that duplicated maud's own escaping), and updates docs/tests/RPC hints consistently across the whole surface—broader, more durable API/UX clarity. Side A is a solid, well-tested small feature (clickable unpin icon) but is narrower in scope and lower overall impact than B's cross-cutting CLI redesign and bugfix.
B reshapes the primary agent CLI surface: replaces loose `ingest`/`forum <title>` with explicit `forum list|show|post`, tightens room-scoped `public`/`private` usage, requires `--delegate` on posts, and updates server next-move hints plus integration tests—lasting API/design clarity. A is a solid, tested UX polish (static pin glyph → real unpin form + CSS), but narrower in scope than B’s command-model change.
Side A implements a concrete user-facing capability by making pinned child-group icons submit the existing `set_garden_pin` unpin flow, wiring the required navigation path through rendering, updating styles, and adding comprehensive browser tests that verify unpin behavior from the ranked list and HUD. Side B is largely a CLI command reshaping and documentation update (`ingest`/`forum` command structure, help text, test adjustments) with limited underlying functionality beyond reorganizing the interface.
comparison · c_7ec4b410de02 (tommy-mor) vs c_a896b2dc05d5 (tommy-mor)
Side A delivers a self-contained, well-tested UI feature (clickable unpin from ranked child list) with corresponding CSS and updated browser test coverage exercising the new flow end-to-end. Side B refactors the recent-votes storage from a capped Deque to an append-only List but removes the write-time trim entirely, meaning storage now grows unbounded per node while only capping at query time—a real scalability regression traded for simplicity, despite the added unit test.
B redesigns the core recent-votes path (Deque/VecDeque → append-only List/Vec, schema v3→v4, drop write-time trim in projection_apply, cap only on load) with a dedicated unit test—lasting storage/reducer simplification. A is a solid but narrower UX win: wiring the existing set_garden_pin clear POST into ranked child pin icons plus CSS and browser coverage.
Side B makes a deeper architectural change by replacing the durable recent-vote deque with an append-only list, removing write-time trimming logic, updating the in-memory representation, bumping the storage schema version, and adding a test that verifies query-time capping. Side A improves usability by making pinned child-group icons submit the existing unpin flow and adds browser coverage, but it is a localized UI enhancement rather than a broader storage/design improvement.
comparison · c_7ec4b410de02 (tommy-mor) vs c_2dc96aace098 (tommy-mor)
B delivers a real architectural improvement—offloading Reddit JSON payloads from the in-memory GlobalTree to a RocksDB-backed EntityStore and switching event-log loading to a streaming replay—backed by new tests (entity_store, event_log, state) that materially reduce startup RAM, a genuine lasting fix. A is a clean, well-scoped UI feature (clickable unpin icon reusing the existing set_garden_pin flow) with matching CSS and a solid browser test, but it's a much smaller, more contained change. B's patch is bloated with vendored crate boilerplate (duplicate Cargo.lock, README, RFC docs, unused examples) that is mostly noise, but the core server-side integration is a nontrivial, correct systems improvement that outweighs A's narrower scope.
B delivers lasting infrastructure: vendoring a RocksDB-backed durable crate, moving full Reddit entity JSON out of in-memory GlobalTree into entity_db, and streaming event-log replay line-by-line to cut startup RAM—plus wiring EntityStore through import/replay paths. A is a focused UX polish (clickable unpin in ranked child rows with CSS/tests) that reuses an existing set_garden_pin flow and does not change core storage or scalability.
Side B introduces substantial architectural changes: it adds a new RocksDB-backed `durable` workspace crate, moves raw entity payloads out of the in-memory tree into a persistent `EntityStore`, changes reducer/state/reddit flows to use it, and replaces whole-log loading with streamed event replay to reduce startup memory, along with integration tests. Side A is a well-scoped UX improvement that makes pinned icons clickable to unpin via the existing `/ui` flow and adds browser coverage, but its impact is localized compared with B's lasting storage and replay infrastructure.
comparison · c_597d3f736194 (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
Side B adds a real user-facing feature (clickable unpin from ranked child groups) with corresponding UI, CSS, and expanded test coverage exercising the new flow end-to-end. Side A is a legitimate but narrow test-infra bugfix (regex split, error handling in mock server, selector-based test helpers) that only improves test reliability rather than product functionality.
A restores broken E2E auth by fixing real mock-server bugs (Clojure `str/split` needing a regex, reading `getRequestBody` instead of `getInputStream`, 302 content-length, null-safe token/state handling, handler error trapping), which unblocks Playwright login flows project-wide. B is a solid but narrower UX polish: wire the existing `set_garden_pin` clear POST into ranked child-row pin icons plus CSS/test coverage, valuable locally but less foundational than repairing auth test infrastructure.
Side A restores broken end-to-end authentication tests by fixing multiple concrete defects in the mock OAuth servers: correct query parsing with regex splitting, reading POST bodies from `getRequestBody`, guarding null bearer tokens/state, using proper redirect response handling, and wrapping handlers to avoid crashes, alongside improving Playwright test selectors and synchronization. Side B adds a useful UI enhancement by making ranked-list pin icons submit the existing `set_garden_pin` unpin flow with supporting CSS and browser tests, but it is a narrower feature addition than A's broad reliability fixes for the project's authentication test infrastructure.
comparison · c_7ec4b410de02 (tommy-mor) vs c_97611919bf0b (tommy-mor)
Side B is a substantial, structural refactor (CanonicalItemUrl -> ItemId enum) touching reducer, ranking, RPC, and types crates with updated tests throughout, which is a deeper architectural investment even though it's riskier and less polished (e.g. Opaque fallback variant, unwraps). Side A is a small, well-scoped UI feature (clickable unpin icon) with a matching CSS and browser test update, useful but narrow in scope and impact compared to the identity-model overhaul in B.
B replaces CanonicalItemUrl with a structural ItemId across types, reducer, ranking, RPC, and HTML and removes the migration plan—core lasting design. A only wires unpin POST forms/CSS/tests onto ranked-child pin glyphs, a small UX surface on an existing flow.
Side B replaces the pervasive `CanonicalItemUrl` string wrapper with a structured `ItemId` type across the reducer, ranking, routing, RPC, path handling, and tests, while adding dedicated `item_id`/`item_wire` modules and updating APIs to use the stronger abstraction. Side A is a useful, well-tested UX improvement that makes ranked child-group pin icons submit the existing unpin flow and adjusts CSS, but its scope is limited to a single interaction whereas Side B establishes a foundational identity model used throughout the project.
comparison · c_11d6a0ec9839 (tommy-mor) vs c_7ec4b410de02 (tommy-mor)
Side B adds genuine user-facing functionality (clickable unpin from ranked child groups) with corresponding CSS and expanded browser test coverage, fixing a real UX gap. Side A is mostly a route rename and minor cleanup (removing a swap button, fixing a fallback edge case), which is useful but smaller in scope and partly cosmetic (renaming /vote/compare to /vote across many call sites).
A fixes real correctness issues: delegate attribution moved out-of-band into rpc_post instead of DSL body text, and sibling-pool < 2 no longer silently falls back to all items. B only adds unpin clickability on ranked child rows (reuse of existing set_garden_pin) plus CSS/tests—useful UX parity but narrower and less foundational than A’s behavior and API fixes.
Side A fixes multiple behavioral issues: it correctly passes delegate attribution out-of-band instead of embedding it in the DSL, stops incorrectly falling back to all items when a sibling pool has fewer than two candidates by returning no next pair, and updates routing from `/vote/compare` to `/vote` consistently across server code and tests. Side B is a solid UX improvement that makes pinned icons in ranked child groups submit the existing unpin flow, but it extends an existing feature rather than correcting several core behaviors.
comparison · c_7ec4b410de02 (tommy-mor) vs c_c6f5afec1d36 (tommy-mor)
Side B adds a genuinely new capability (pool-scoped voting across a parent's children, with query param handling, next-pair suggestion within a pool, and threading through post-success JS) touching multiple files with real logic changes. Side A is a smaller, more narrowly-scoped UI improvement (making pin icons clickable to unpin) that mainly adds a form/button and CSS tweaks plus updates a browser test, which is useful but less substantial in scope and design impact than B's feature addition.
B adds a real product capability (pool-scoped /vote, first-unvoted pair selection from children, pool-aware next-pair nav, and a “vote on children” entry point) threaded through query parsing, pair suggestion, UI actions, and success JS. A is a focused UX win—turning a static ranked-list pin glyph into an unpin form reusing set_garden_pin plus CSS/tests—but it is incremental polish, not a new voting model.
Side B introduces a substantial new capability: pool-scoped voting by adding a `pool` parameter throughout the vote flow, enabling `/vote?pool=<parent>` to choose sibling pairs, preserving pool context across navigation and vote submissions, and exposing the feature with a new 'vote on children' entry point. Side A is a focused UX improvement that makes pinned child-group icons clickable to unpin via the existing `set_garden_pin` flow, with supporting CSS and browser tests, but it extends an existing interaction rather than adding comparable new functionality.
comparison · c_7ec4b410de02 (tommy-mor) vs c_c25451965a7f (tommy-mor)
Side B fixes a real, systemic bug (hardcoded staging hostnames breaking OAuth callbacks and redirects across multiple services) by consolidating logic into a single util.get-base-url helper, reducing duplication and future maintenance burden across 6+ files. Side A is a legitimate but narrow UI feature (clickable unpin icon) with reasonable test coverage, but it's more localized and lower-impact than fixing broken cross-service redirect infrastructure.
B fixes a systemic correctness issue by replacing duplicated hardcoded host cases (oauth/linear/spotify/twitter/youtube/login plus frontend authUtils) with a shared HOSTNAME-aware get-base-url and window.location.origin, and wires deploy to staging—lasting multi-host infra. A is a solid but localized UX win: the ranked-list pin becomes an unpin POST form with theme CSS and an extended browser test, reusing an existing flow rather than foundation design.
Side B consolidates base-URL generation into a shared util function, replaces multiple hardcoded host/environment checks across OAuth and callback flows with a single HOSTNAME-aware implementation, and updates the frontend to use window.location.origin, improving portability for custom hosts. Side A adds a useful UI enhancement by making pinned child-group icons submit the existing unpin flow and backs it with browser tests, but its impact is confined to a specific interaction rather than infrastructure used across many authentication and redirect paths.
comparison · c_7ec4b410de02 (tommy-mor) vs c_1c1c8e7a2de8 (tommy-mor)
Side B removes dead/unused complexity (ThreadVisibility, unused RoomState field, HashMap→HashSet simplification) and adds a genuinely useful CLI command (`room create`) with docs and tests updated across multiple layers (rpc.rs, events.rs, reducer.rs, timeline.rs, CLI, integration tests, bb tests). Side A is a smaller, focused UI feature (clickable pin/unpin) with decent browser test coverage but touches fewer architectural layers and has more narrowly scoped value.
B adds a real CLI `room create` path and simplifies the domain by dropping ThreadVisibility/RoomState so rooms are a HashSet of private ids, touching RPC, events, reducer, types, docs, and tests—structural product surface. A only wires an existing set_garden_pin clear into ranked child pin glyphs plus CSS/test updates, a useful but localized UX polish.
Side B adds a new top-level CLI `room create` command wired through to the RPC, updates the server to support the simplified `RoomCreate` flow, removes the unused room visibility concept from events/reducer state, and updates documentation and tests accordingly. Side A is a solid UX improvement that makes ranked child pin icons submit the existing `set_garden_pin` unpin action and adds browser coverage, but it is a narrower interface enhancement compared with B's broader, lasting API and architecture simplification.
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_7ec4b410de02 (tommy-mor) vs c_64faa3bee86f (tommy-mor)
Side B unifies the auth flow with the shared layout/JS pattern (removing a bespoke redirect-based layout, adding inline error/success fragments and generalizing the poem-JS morph behavior), which is a real architectural simplification with broader reuse. Side A is a solid, well-tested UX addition (unpin from ranked list) but is more narrowly scoped and mostly wiring/CSS/test changes rather than structural improvement.
B redesigns auth POST handling to return HTML fragments and extends the shared poem form interceptor to morph non-empty responses, replacing redirect round-trips with inline error/success—structural UX that affects the whole auth path. A only wires an existing set_garden_pin clear action onto ranked-child pin glyphs (plus CSS/tests), a useful but localized consistency fix.
Side B changes the auth flow architecture by returning HTML fragments instead of redirects, refactoring the username form into reusable rendering helpers, and extending the shared Poem JavaScript to morph a form's innerHTML when a POST returns HTML, enabling inline form updates without page reloads while preserving existing empty-response behavior. Side A is a solid UX improvement that makes ranked child-group pin icons submit the existing unpin action and adds browser coverage, but it is a narrower feature built on an existing flow rather than a reusable interaction pattern.
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_7ec4b410de02 (tommy-mor) vs c_57453fc5c6c0 (tommy-mor)
Side B introduces a complete, reusable feature (garden ranking markdown copy) with a new module, unit tests for markdown formatting, a full integration test asserting JS/clipboard behavior, and doc updates in agents.md, wiring it cleanly through the existing HtmlUiAction/JsBuilder pattern. Side A is a solid but narrower UX fix (making pin icons clickable) touching CSS/markup and one browser test, with less new reusable functionality and no unit/integration test coverage beyond the browser flow.
B adds a full feature path (new CopyGardenRank action, garden/copy.rs markdown rebuild + clipboard JsBuilder flow, UI hooks on ranking headings, unit/integration/browser coverage and agents.md notes), which is lasting product surface. A only turns an existing static 📌 into an unpin form reuse of set_garden_pin plus CSS/test tweaks—useful UX polish, but much narrower than B’s end-to-end capability.
Side A fixes a concrete usability gap by making the pinned icon in ranked child groups perform the existing unpin flow (`set_garden_pin`), wiring the required redirect path through rendering, updating styles for the new button, and adding an end-to-end browser test covering both ranked-list and HUD unpin behavior. Side B adds a useful markdown copy feature with new UI actions, rendering, and tests, but it is primarily an additive convenience feature rather than resolving an inconsistency in core interaction.
comparison · c_7ec4b410de02 (tommy-mor) vs c_477013996fa5 (tommy-mor)
B implements a real functional fix (the vote-compare preview card was previously not morphed into the DOM at all, plus adds correct ratio-oriented sorting relative to page left/right and a dedicated fullscreen layout) backed by a new unit test verifying sort correctness. A is a smaller, focused UX improvement (clickable unpin icon) that is solid but narrower in scope and mostly wiring/CSS/test churn rather than fixing a functional gap.
B adds lasting design: chromeless fullscreen compare layout, correct left/right ratio orientation, strength-based edge-history sort, and post-success morph of the new ingest card, backed by unit and browser tests. A is a useful but narrower UX polish—turning a static pinned glyph into the existing set_garden_pin unpin form with CSS and e2e coverage—without comparable structural or correctness impact.
Side B makes a substantial functional improvement to the vote-compare workflow: it adds a chromeless fullscreen layout, updates the POST success path to morph both the new vote preview and refreshed edge history, fixes edge-history presentation by orienting ratios to the current page's left/right items and sorting by preference strength, and adds regression tests for the new behavior. Side A is a focused usability enhancement that makes pinned child-group icons clickable to unpin via the existing /ui flow with matching CSS and browser coverage, but its scope is much narrower than the architectural and behavior changes in Side B.