comparison · c_5e9a63e9d276 (tommy-mor) vs c_55666fe32c48 (tommy-mor)
B is a small, focused correctness fix (enforcing valid vote ratio bounds across DSL parser, UI handler, and reducer) with targeted regression tests and a real behavioral improvement preventing degenerate/invalid votes. A is a large mechanical refactor moving code into a new types module with newtypes wrapping strings, which improves type-safety/organization but is mostly churn (renames, re-exports, moved tests) without fixing any bug or changing runtime behavior, and risks regressions across many call sites for marginal clarity gains.
B enforces a real ranking invariant (both ratio sides ≥ 1 and ≤ 100) in the DSL parser, UI POST path, and reducer (dropping zero-side votes instead of normalizing 0:0→1:1), with unit and integration regression tests. A mostly relocates existing canonicalize/path helpers into slug-types and wraps API strings in GardenItemUrl/ForumThreadUrl/TildeOntologyPath—useful structure, but largely mechanical re-export and call-site rewiring without fixing domain behavior. A precise multi-layer correctness fix outlasts diffuse type centralization alone.
Side A performs a substantial architectural refactor by moving canonicalization, path identity, and room-aware URL generation into shared `slug_types::paths` newtypes (`GardenItemUrl`, `ForumThreadUrl`, `TildeOntologyPath`) and updating API/RPC types to use those abstractions instead of ad hoc string helpers. Side B is a valuable correctness fix that consistently enforces vote ratio bounds (both sides 1–100) across the parser, UI, reducer, and tests, but its scope is a targeted validation improvement rather than a foundational API and type-system redesign.
comparison · c_55666fe32c48 (tommy-mor) vs c_76e946cb1d07 (tommy-mor)
Side A fixes a real bug (zero-ratio votes silently defaulting to 1:1 instead of being rejected/dropped) and adds bounded validation consistently across the DSL parser, HTTP handler, and reducer, backed by new unit and integration regression tests. Side B is purely cosmetic renaming (canonical -> item/wire) with no behavioral change and no new tests, offering only marginal clarity value.
A adds real validation (reject 0:N and >100 ratios) across DSL, UI handler, and reducer, plus targeted unit/integration/browser test updates—lasting correctness for the ranking graph. B is almost entirely renames/comment wording (canonical→item, pick_random_distinct_*) with no meaningful behavior change.
Side A implements a substantive correctness change by enforcing vote ratio bounds (both sides at least 1 and at most 100) across the DSL parser, UI POST handler, and reducer, preventing invalid graph edges and adding unit, integration, and browser regression tests. Side B is almost entirely terminology cleanup and renaming (e.g. canonical→item, function and comment renames, removal of a small helper) without materially changing project behavior.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side B is a concrete, tested bugfix/feature: it enforces sane vote-ratio bounds across DSL parsing, HTTP handler, and reducer, with matching unit/integration test updates and a corrected browser test fixture. Side A is only a planning document plus a thin, largely unused RouteContext wrapper that duplicates existing ThreadNav methods without migrating any call sites, providing no functional change or bugfix.
B enforces real vote-ratio invariants (both sides ≥ 1, ≤ 100) across DSL parse, UI POST, and reducer, with unit/integration/browser test coverage—fixing invalid graph edges. A mainly adds a staging plan.md plus a thin RouteContext newtype around ThreadNav without migrating call sites or landing ItemId, so its lasting code impact is scaffolding only.
Side B implements a real behavioral change by enforcing valid vote ratios across the DSL parser, HTML POST handler, and reducer, preventing zero-weight graph edges and capping ratios at 100, while adding unit, integration, and browser test updates to lock in the behavior. Side A mainly adds a planning document plus a thin `RouteContext` wrapper and re-export without migrating callers or changing core functionality, so its lasting project impact is much smaller.
comparison · c_45dfa34511fe (tommy-mor) vs c_55666fe32c48 (tommy-mor)
A consolidates duplicated room-id/slug splitting logic into a single `room_route_segment`/`room_id_from_route_segment` API (used consistently across UI, API, and tests) and adds a well-tested external-URL normalization module (YouTube canonicalization, query sorting) that improves identity correctness for garden items—substantial, tested infrastructure work. B is a narrower but solid correctness fix (rejecting invalid vote ratios) with good test coverage, but it's much smaller in scope and impact compared to A's broader refactor and new normalization capability.
A lands lasting shared design: fixed-width `/r/{short}{slug}` encoding (`room_route_segment`/`room_id_from_route_segment`), route/handler consolidation, and external identity normalization (YouTube rewrite, sorted query pairs, case-preserving dash paths) with broad call-site and test updates. B is a correct but narrow domain guard—reject 0-sided and >100 vote ratios in DSL, UI POST, and reducer, plus regression tests—valuable integrity work that does not match A’s reusable URL architecture impact.
Side A introduces a substantial, cross-cutting URL and routing refactor: it centralizes room route encoding/decoding with new `room_route_segment`/`room_id_from_route_segment` helpers, updates server routing and URL generation to a unified `/r/{room_key}` format, and adds URL normalization infrastructure (including canonicalization improvements and tests). Side B is a focused validation change that enforces vote ratio bounds across the parser, UI, and reducer with appropriate regression tests, but its impact is narrower than the architectural routing and URL normalization work in Side A.
comparison · c_8dc1a8119370 (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side A eliminates ~1800 lines of an overengineered, unreliable keystroke-transition graph parser and replaces it with a much simpler, testable URL-extraction function plus a paste-and-go UI, removing significant tech debt and a whole class of race-condition bugs (also dropping the now-obsolete Playwright race test). Side B is a solid, well-tested correctness fix (enforcing vote ratio bounds across DSL/UI/reducer) but is narrower in scope and impact than A's architectural simplification.
A removes an unreliable ~1.8k-line keystroke transition graph, ParserAction surface, race-prone JS debounce path, and Playwright race test, replacing them with a small deterministic URL→subreddit parser and paste-and-Go redirect that actually ships navigation. B is a real, well-tested domain fix (reject 0:* / *:0 and >100 ratios in DSL, UI handler, and reducer) but is a narrow constraint layer versus A’s lasting simplification of a broken subsystem.
Side B adds a durable correctness constraint across the whole stack: it rejects invalid vote ratios (either side <1 or >100) in the DSL parser, UI handler, and reducer, preventing meaningless graph edges while adding regression tests for parser, reducer, integration, and browser behavior. Side A mainly replaces a complex autocomplete/transition-graph UI with a simpler paste-and-go flow, removing substantial functionality and tests while simplifying URL parsing, which is a product-direction change rather than a clear long-term correctness improvement.
comparison · c_0c466eea1ed4 (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side B fixes a real correctness/data-integrity gap (0-ratio votes silently defaulting to 1:1, unbounded ratios skewing scores) consistently across DSL parser, browser handler, and reducer, with regression tests and an updated integration test proving the fix; this is a genuine bugfix with lasting behavioral impact. Side A adds a sizable new dev-only binary and offline module, which is useful tooling but is additive, not fixing any existing defect, and its value is more speculative/convenience-oriented than a correctness guarantee.
B hardens a core domain invariant (vote ratios both ≥1 and ≤100) in the DSL parser, UI handler, and reducer, with unit/integration/browser coverage—preventing invalid graph edges in production ranking. A adds useful offline compile/scan tooling and docs, but it is workspace-only developer convenience and does not change runtime correctness the way B does.
Side B fixes a correctness issue by enforcing meaningful vote ratio bounds (both sides must be at least 1 and at most 100) consistently in the DSL parser, UI handler, and reducer, preventing zero-weight or extreme votes from creating invalid graph behavior. It also updates affected tests and adds parser, integration, and UI regression tests, whereas Side A primarily adds a useful developer-facing offline tool without changing core runtime correctness.
comparison · c_48edc893c5b0 (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side B is a small, well-justified bugfix: it closes a real correctness gap (zero-ratio votes silently coerced to 1:1, no upper bound) and consistently enforces the invariant across DSL parser, HTTP handler, and reducer, backed by targeted unit/integration tests. Side A is a larger scaffolding commit (new form-template/ui_action machinery) that adds real infrastructure but is mid-progress ('progress' commit message), more speculative/generic, and lacks the same tight problem/fix correspondence.
A adds lasting foundation: form_template hole-fill, HtmlUiAction + POST /ui, shared run_* web_post paths, and expand-in-place new-thread UI—architecture later commits build on. B is a correct but narrow multi-layer vote-ratio guard (≥1, ≤100) with tests; valuable domain tighteness, but smaller scope than A’s design surface.
Side A introduces a substantial new UI architecture: a unified POST /ui endpoint, the HtmlUiAction command model with JSON template parsing and form-hole substitution, reusable web action handlers, and integration into routing and forum rendering. Side B is a valuable correctness fix that consistently enforces vote-ratio bounds (both sides >=1 and <=100) across the parser, UI handler, reducer, and tests, but it is a comparatively localized validation change rather than a broad, reusable capability.
comparison · c_c6f5afec1d36 (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side B fixes a real correctness/data-integrity issue (invalid 0:0 or extreme ratios silently normalized or unbounded) with enforcement at three layers (DSL parser, HTTP handler, reducer) plus solid unit and integration regression tests. Side A adds a useful feature (pool-scoped voting) but with less test coverage of the new branching logic and edge cases, making B's change more clearly correct and durable relative to its scope.
A adds a real product capability: pool-scoped pair selection and next-pair navigation, a children UI entry point, and pool threading through the vote POST/success path. B is a smaller but solid multi-layer correctness guard (parser, UI handler, reducer) with good regression tests; it improves data integrity without expanding what users can do.
Side A adds a substantial new capability: pool-scoped voting, allowing `/vote?pool=...` to automatically select child-item pairs, preserving pool context through navigation and postback, and exposing the feature via a new 'vote on children' UI. Side B is a solid correctness improvement that enforces valid vote ratios consistently across the UI, DSL parser, reducer, and tests, but it primarily tightens validation of an existing feature rather than expanding the project's functionality.
comparison · c_55666fe32c48 (tommy-mor) vs c_abd68b5e771a (tommy-mor)
Side A introduces the actual feature (ratio bounds enforcement across DSL parser, HTTP handler, and reducer) with substantial regression/integration test coverage, providing real user-facing validation and lasting behavior change. Side B is a small, valid follow-up bugfix correcting an ordering issue in A's own reducer logic (ghost items/pair marking), which is useful but narrower in scope and dependent on A's prior work.
A establishes the lasting vote-ratio invariant end-to-end (DSL parse, UI POST rejection, reducer drop, max≤100) with broad unit/integration/browser coverage. B only relocates A’s zero-ratio early-return before ensure_item/voted_pairs and tightens one test—important correctness, but a narrow follow-up versus A’s multi-layer design.
Side A establishes the core invariant that vote ratios must have both sides between 1 and 100 by enforcing it in the DSL parser, UI POST handler, and reducer, and adds regression tests covering parser and integration behavior. Side B is a worthwhile follow-up that fixes a reducer edge case by moving the zero-ratio early return before item registration and voted-pair insertion, preventing ghost state, but it is a narrower correction built on the broader validation introduced by Side A.
comparison · c_e57094c6229a (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side A delivers a substantial, coherent feature: it moves entity fetching from implicit auto-fetch to explicit user-initiated fetch, persists the raw API payload as an event (EntityImported) for proper replay/audit, decouples Reddit API base URLs for testability, and adds fixtures plus an integration test proving end-to-end behavior—real architectural and correctness improvements. Side B is a smaller, well-scoped bugfix enforcing ratio bounds (1-100) with matching parser/reducer/handler changes and tests, which is valuable but narrower in scope and impact than A's persistence/event-sourcing and fetch-control redesign.
A redesigns Reddit/entity import into a durable path: full payloads via EntityImported events, replay into entity_raw + derived views, explicit user-driven fetch UI, configurable API bases, and an end-to-end mock integration test—core lasting architecture. B correctly hardens vote ratios (≥1, ≤100) across DSL, UI, and reducer with solid tests, but it is a narrow constraint fix versus A’s broader durable design change.
Side A introduces a durable architectural improvement: it replaces automatic Reddit fetches with an explicit user-triggered fetch flow, persists full imported API payloads as `EntityImported` events for replay, stores raw entity data alongside derived views, adds configurable API endpoints, and includes replay/integration tests. Side B is a solid correctness fix that consistently enforces valid vote ratios (1–100) across the parser, UI handler, reducer, and tests, but its scope is limited to input validation and guarding invalid graph edges.
comparison · c_55666fe32c48 (tommy-mor) vs c_2f5d9e0370f8 (tommy-mor)
Side A fixes a real logic bug (zero-ratio votes silently defaulted to 1:1 instead of being rejected/dropped) and adds sensible bounds with focused, well-tested changes across parser, handler, and reducer. Side B is a large syntax-reordering refactor (moving explanation blocks before votes/items) that touches many files and fixtures but is mostly mechanical churn with no functional bugfix, and even changes the DSL in a way that could be seen as a regression in ergonomics (losing adjacent-body syntax).
B redesigns the core DSL so vote explanations lead and item bodies trail paths, rewriting the parser (block-prefixed votes, pending-block handling) and aligning docs, UI emit paths, and fixtures—lasting product grammar. A only tightens ratio bounds (≥1, ≤100) in parser/UI/reducer with tests; correct and useful, but a narrow validation fix atop existing semantics.
Side A introduces substantive validation by enforcing vote ratios of 1–100 in the DSL parser, browser POST handler, and reducer, preventing invalid zero-weight edges and unbounded ratios while adding focused regression and integration tests. Side B primarily performs a sweeping DSL syntax migration (moving vote explanations before comparisons) and updates documentation, fixtures, UI formatting, and tests to match, with comparatively little new functional behavior beyond the syntax change.
comparison · c_55666fe32c48 (tommy-mor) vs c_cd965c070df3 (tommy-mor)
Side B fixes a real functional bug (Reddit children imports bypassing ensure_path and showing raw IDs instead of titles), threading tree context through several call sites and updating integration tests to verify the fix. Side A tightens validation constraints (0:0 handling, max 100) which is useful but more incremental/policy-level, with much of its diff being test churn and message-text changes rather than new behavior.
B fixes real Reddit import behavior by replacing incomplete link_child/ensure_path wiring with apply_entity_under_parent so listing children attach under the subreddit without comment-path segments, and makes unranked labels use entity titles via child_label/ranking_panel(tree). A only tightens vote-ratio validation (reject 0-sides and >100) across parser/UI/reducer with regression tests—useful invariants, but less product-critical than the import and display fix.
Side A closes a correctness gap by enforcing vote ratio constraints consistently across the DSL parser, browser POST handler, and reducer, preventing invalid zero-sided votes and oversized ratios while adding targeted unit and integration regression tests. Side B fixes Reddit child import attachment and improves unranked labels by importing children under the intended parent and passing tree context into the ranking panel, but its impact is narrower to the Reddit import/UI path compared with A's project-wide data validation and invariant enforcement.
comparison · c_2722a3195825 (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side A meaningfully improves the core pairwise-comparison algorithm (the product's central ranking mechanism), adding principled sub-priorities for merging established components before isolates and zipping adjacent ranks, backed by targeted new tests validating each scenario. Side B fixes a real but narrower validation gap (zero/over-100 ratios) consistently across DSL, HTTP handler, and reducer with good test coverage, but it's an edge-case guard rather than a design improvement to core functionality.
A redesigns core pair selection with lasting ranking-hub behavior: bridge sub-priorities (merge established → attach isolate → isolate pair) and rank-adjacent zip refinement once the pool is connected, backed by targeted unit tests. B is valuable multi-layer input validation (reject 0 and >100 ratios in DSL, UI, and reducer) but is a narrower correctness guard than A’s algorithm change to the main voting loop.
Side B enforces consistent vote-ratio validation across the DSL parser, UI handler, and reducer, preventing invalid zero-sided votes from creating graph inconsistencies and adding comprehensive regression and integration tests. Side A improves pair-selection heuristics by prioritizing attachment to established components and rank-adjacent refinement, but those are algorithmic refinements rather than the broad correctness and input-validation guarantees introduced by Side B.
comparison · c_4772ee88dbe3 (tommy-mor) vs c_55666fe32c48 (tommy-mor)
Side B fixes a real correctness/validation gap (rejecting invalid 0-sided and >100 vote ratios) consistently across parser, HTTP handler, and reducer, with matching test coverage, closing a genuine bug where 0:0 silently became 1:1. Side A is a mixed refactor that removes demo scaffolding (fine) but also introduces an async settlement-worker architecture with caching that changes vote-application semantics and concurrency behavior without clear justification or equivalent test rigor, making it riskier and less clearly a net positive.
A delivers lasting architecture: a settlement worker that batches votes, persists events, and recomputes ranking scores off the request path, plus read-only cached ranking and removal of the throwaway demo-counter path. B is a sound multi-layer validation fix (ratios ≥1 and ≤100 in DSL, UI, and reducer) with solid tests, but it is a narrower correctness guard than A’s design change.
Side A delivers a substantial architectural improvement: it removes the temporary demo counter feature, introduces a dedicated settlement worker that batches vote persistence and ranking recomputation, adds cached ranking reads (`ranked_items_cached`), warms the cache on startup, and switches HTTP paths from write locks to read locks for ranking display. Side B is a solid correctness change that consistently enforces vote ratio bounds (1–100) across the UI, DSL parser, reducer, and tests, but it is a narrower validation fix compared with A's broader, lasting simplification and performance-oriented redesign.