comparison · c_a154a1e4f1df (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Commit B makes a substantially larger contribution. It introduces a new `RouteContext` abstraction with a dedicated routing module, exports it for use across the HTML layer, and adds a detailed engineering plan documenting the intended `ItemId`/routing refactor, migration phases, risks, and testing strategy. While much of the added content is documentation, it also includes reusable code that establishes a new API for route generation. Commit A is a small cleanup that removes a UI preview section from a template, which is a much narrower change with limited architectural impact.
Side B introduces a substantial architectural plan document and a new routing module with supporting exports, adding meaningful structure and future guidance to the codebase. Side A only removes a small HTML section with minimal impact.
Commit A removes a small HTML section (a few lines of DOM). Commit B introduces a substantial architectural planning document (~155 lines) plus a new routing module with RouteContext (~70+ lines) and integrates it into the HTML module. This adds significant structural groundwork and documentation for future refactoring, far outweighing the minor UI removal in A.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_5cd3e5917d2f (tommy-mor)
Commit B makes a substantial architectural and behavioral change across the codebase. It removes persistent storage of Reddit payloads from the event log, deletes the EntityStore subsystem, changes the event model by eliminating EntityImported events, introduces ephemeral projection-cached content with TTL-based eviction, updates the journal, projection pipeline, Reddit importer, storage schema, application state, tests, and documentation/comments to match the new design. This changes persistence semantics, privacy/data-retention behavior, and replay logic while adding new functionality and migration of many call sites. Commit A primarily adds a detailed planning document plus a small RouteContext wrapper module and re-export. While the design document is valuable for future work, it has minimal runtime impact compared with the extensive implementation in commit B.
Commit B makes a sweeping architectural change: it removes the persistent EntityStore and the EntityImported event, redesigns how Reddit data is handled (ephemeral projection-only with TTL eviction), updates the event model, projection pipeline, storage schema, background jobs, and many tests. This significantly alters system behavior, storage guarantees, and data flow across the codebase. Commit A mainly adds a planning document and a thin RouteContext wrapper with minimal functional impact. The scale and depth of B’s changes far exceed A.
Commit B makes sweeping architectural changes: it removes the EntityStore and EntityImported event, rewires journal and projection layers, updates storage schema and DTOs, introduces ephemeral Reddit content with TTL eviction, modifies reducers, state initialization, background tasks, and adjusts Rust and Clojure tests accordingly. This significantly changes data durability semantics and system behavior. Commit A mainly adds a planning document and introduces a small RouteContext wrapper module with minimal integration impact. Therefore, B contributes far more substantial functionality and structural change.
comparison · c_a154a1e4f1df (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Commit B introduces a substantive new abstraction (RouteContext wrapping ThreadNav with concrete methods) plus a detailed migration plan document that provides real architectural direction and lasting reference value for future refactors. Commit A is a trivial one-line-block removal of dead HTML markup, which is useful cleanup but minor in scope and impact compared to B's added scaffolding and documentation.
B adds lasting structure: a real RouteContext API in routing.rs (and re-exports) plus a concrete ItemId migration plan that unblocks a core identity/routing refactor. A only deletes a small unused vote-preview DOM block—a correct cleanup, but far narrower impact than B’s design foundation.
Side B introduces a new `RouteContext` abstraction in `server/src/html/routing.rs`, re-exports it from `html/mod.rs`, and centralizes scoped URL-building behind methods like `item_href`, `thread_url`, and `garden_root_url`, creating a reusable foundation for future routing changes. Side A only removes a `vote-compare-preview` HTML block from `garden.rs`, which is a localized UI cleanup with much narrower long-term impact.
A simply removes a small HTML preview block (`vote-compare-preview-wrap`), reducing UI without clear functional gain. B introduces a new `routing.rs` module with `RouteContext` abstraction and wires it into `html/mod.rs`, establishing a centralized path-building design that affects future HTML and routing consistency, plus a detailed plan guiding a large refactor.
Side A simply deletes a small HTML preview section (`vote-compare-preview-wrap`) from `garden.rs`, removing UI without adding structural improvement. Side B adds a substantial architectural plan (`plan.md`) and introduces a new `RouteContext` abstraction in `server/src/html/routing.rs`, re-exported in `html/mod.rs`, establishing a centralized routing layer for scoped href generation—an extensible design change with lasting impact.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_5cd3e5917d2f (tommy-mor)
Side B is a substantive, tested architectural change: it removes the EntityStore/EntityImported design, replaces it with ephemeral projection-only Reddit content plus a TTL eviction task, updates the event log schema, storage schema, journal wiring, and adjusts/fixes both Rust and Clojure tests to match the new behavior. Side A is purely a planning document (plan.md) plus a thin, mostly unused RouteContext wrapper that just delegates to existing ThreadNav methods—useful as a roadmap but no functional or tested change to the running system.
B removes EntityImported/EntityStore, keeps Reddit payloads out of the durable log, and adds projection-only caching with 48h TTL eviction—real architecture, API-policy, and test changes across events, journal, storage, and reddit import. A mostly adds a temporary plan.md plus a thin RouteContext newtype that delegates to existing ThreadNav methods, with no ItemId migration or lasting bugfix.
Side B makes a substantive architectural change: it removes persistent storage of Reddit API payloads and the `EntityImported` event, replaces them with ephemeral projection-cached display content plus TTL eviction, updates replay/journaling/projection logic accordingly, and adds tests reflecting the new persistence model. Side A primarily adds a planning document and introduces a thin `RouteContext` wrapper re-export without migrating callers or changing runtime behavior, so its lasting project impact is much smaller.
Side B makes a deep architectural change: it removes `EntityStore` and the `EntityImported` event entirely, rewrites projection application to exclude payload persistence, and introduces ephemeral caching with TTL eviction (`put_ephemeral_content`, `evict_content_older_than`) plus updated tests. Side A mainly adds a planning document and a thin `RouteContext` wrapper delegating to `ThreadNav`, with minimal functional impact.
Side B fundamentally redesigns persistence by deleting `EntityStore` and the `EntityImported` event, moving Reddit payloads out of the event log and into TTL-evicted ephemeral projection storage with new `put_ephemeral_content` and eviction logic, plus updated tests and schema versioning. Side A only adds a planning document and a thin `RouteContext` wrapper around `ThreadNav` without changing behavior, so its impact is preparatory rather than substantive.
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_ebc883667d61 (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Side A is a real, verified refactor: it deletes the stale monolithic forum.rs and moves all its logic into the already-existing forum/ submodules, resolving a module-resolution ambiguity and preserving working functionality across many call sites. Side B is a speculative planning commit that adds an unfinished plan.md and an unused RouteContext wrapper that isn't actually wired into any call sites, providing no concrete behavioral value yet.
A removes a leftover 1400-line monolithic forum.rs that conflicted with the forum/ tree, making the split modules the sole root—a real compile/structure fix with lasting maintainability. B mostly adds ephemeral plan.md plus a thin RouteContext newtype over ThreadNav with no call-site migration, so little shipped design yet.
Side A removes the duplicate `server/src/html/forum.rs`, introduces `forum/mod.rs`, and moves the existing implementation into focused submodules (`feed.rs`, `views.rs`, `thread_morph.rs`, etc.), eliminating module-resolution ambiguity so `mod forum` has a single authoritative root. Side B mainly adds a detailed planning document plus a thin `RouteContext` wrapper and export, which lays groundwork but leaves most call sites unchanged and delivers little immediate functional value.
comparison · c_f6d0fed9bf9a (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Side A's diff is mostly a noisy dump of already-existing files pasted at the repo root, with literal shell-prompt artifacts (`tommy@Tommys-Laptop:~/...⇒ cat ...`) embedded inside the '.rs' content, meaning these are not real, buildable additions integrated into the actual server/src tree. Side B, though much smaller, adds a real, properly wired module (`routing.rs`/`RouteContext`) integrated into `html/mod.rs`, plus a clear, actionable refactor plan (`plan.md`) that gives concrete lasting guidance for future work — substance over spectacle.
Side B delivers a precise, lasting architectural foundation: a complete phased plan for structural ItemId (replacing stringly CanonicalItemUrl) plus the clean RouteContext wrapper and export that begins migratable href generation. Side A is a noisy bulk dump of prototype files (parser/reducer/ranking/vote plus .tdsl notes) that includes terminal garbage embedded in forms.rs and ranking.rs, making much of the large diff non-lasting churn rather than polished design.
Side B introduces a concrete architectural abstraction (`RouteContext`) for centralized HTML route generation, re-exports it from the HTML module, and documents a coherent migration plan toward structured `ItemId` handling. Side A is much larger, but it mixes many unrelated additions with obvious accidental terminal transcript text embedded at the start/end of files such as `forms.rs` and `ranking.rs`, reducing the reliability and lasting value of the patch despite its scope.
comparison · c_28dfd8015c8a (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Side A is a small, concrete fix that removes a real maintenance hazard (manually enumerated test namespaces going stale) and verifiably keeps CI working, delivering immediate lasting value. Side B is almost entirely a speculative planning document (plan.md) with a thin, unfinished RouteContext wrapper that duplicates ThreadNav without migrating any call sites, so its actual code contribution is minimal and mostly aspirational.
A lands a complete, permanent fix: one `^test\..+` suite so new tests (e.g. ranking) run without hand-editing `tests.edn`. B mostly adds ephemeral `plan.md` plus a thin `RouteContext` newtype over `ThreadNav` with no call-site migration or `ItemId` work, so little lasting product value ships yet.
Side A replaces manually enumerated Kaocha test suites with a single auto-discovered `:all` suite using `^test\..+`, so new `test.*` namespaces run automatically without updating `tests.edn`, reducing ongoing maintenance and preventing missed tests. Side B mostly adds a large planning document plus a thin `RouteContext` wrapper around `ThreadNav` with re-exports and forwarding methods, which establishes an abstraction but introduces little immediate functional change.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_a896b2dc05d5 (tommy-mor)
Side B is a real, tested code change: it replaces a Deque-based recent-votes storage with an append-only List, removes now-dead trim logic, bumps the schema version, and adds a passing test verifying cap behavior on read—concrete lasting value to the storage layer. Side A is purely a planning document (plan.md) plus a thin, largely unused RouteContext wrapper that doesn't migrate any real call sites, offering speculative direction rather than delivered functionality.
B makes a lasting design change: recent votes become append-only Vec/List with query-time capping, drops write-path trim and BTreeSet bookkeeping, bumps the projection schema, and adds a regression test. A mostly adds a temporary plan.md plus a thin RouteContext newtype over ThreadNav with no call-site migration, so it is scaffolding rather than shipped substance.
Side B makes a functional architectural change by replacing the durable recent-vote deque with an append-only list, removing post-write trimming, updating the in-memory representation to `Vec`, bumping the storage schema version, and adding a test that verifies query-time capping of recent votes. Side A mostly adds a detailed planning document plus a thin `RouteContext` wrapper re-export around `ThreadNav`, which introduces little immediate behavior beyond an API convenience layer.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_2dc96aace098 (tommy-mor)
Side B is a real, working feature: it vendors a durable RocksDB crate, moves entity JSON out of the in-memory tree into on-disk storage, switches event-log loading to a streaming replay API, and updates reducer/state/reddit modules plus tests to match, directly cutting startup RAM and adding persistence infrastructure. Side A is only a planning document (plan.md) plus a thin, largely unused RouteContext wrapper that still delegates to the old ThreadNav/CanonicalItemUrl string logic, contributing no functional change or bugfix to the codebase.
B delivers a real lasting architecture fix: offloads heavy Reddit entity JSON from the in-memory GlobalTree into a RocksDB-backed EntityStore, streams event-log replay line-by-line to cut startup RAM, and wires those changes through reducer/reddit/state. A only adds a thin RouteContext newtype plus a plan.md checklist for a future ItemId migration, with almost no shipped behavior change.
Side B makes lasting architectural changes: it introduces a RocksDB-backed `durable` workspace crate, adds an `EntityStore` to move raw Reddit JSON off-heap, changes reducer state to stop storing raw payloads in memory, and rewrites event log replay to stream events line-by-line instead of loading the entire log. Side A mainly adds a detailed migration plan document plus a thin `RouteContext` wrapper and re-export, which is useful guidance but contributes little functional behavior compared with B's concrete storage and startup-memory improvements.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_9e1ff4fc0186 (tommy-mor)
Side A introduces a substantive architectural artifact (RouteContext wrapper plus a detailed migration plan for ItemId/routing) that guides real future refactoring work, even if incomplete. Side B is almost entirely mechanical rustfmt/tooling churn (reformatting durable/* examples and tests, toolchain pinning, vscode settings) with only a trivial CSS dedup and no functional improvement, offering little lasting design value beyond formatting consistency.
A adds lasting design value: a concrete RouteContext API (routing.rs + re-export) and a detailed ItemId migration plan that stages real architecture work. B is almost entirely rustfmt churn across examples/lib plus minor toolchain/VS Code pins and a one-line CSS merge, with negligible lasting product substance.
Side A introduces a new `RouteContext` abstraction (`server/src/html/routing.rs`) and exports it from `server/src/html/mod.rs`, creating a centralized API for scoped URL generation (`item_href`, `thread_url`, room/public handling) that supports an ongoing architectural refactor. It also adds a detailed migration plan (`plan.md`) documenting the intended replacement of `CanonicalItemUrl` with `ItemId` and the phased implementation strategy, whereas Side B is overwhelmingly workspace-wide formatting plus tooling configuration (`rust-toolchain.toml`, VS Code settings) with only a minor CSS rule merge and no substantial behavioral change.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_e4fb43f04791 (tommy-mor)
Side A is entirely a planning markdown file plus a thin unused RouteContext wrapper that duplicates ThreadNav without any call sites migrated to it, contributing no functional change yet. Side B makes a concrete UI fix (removing an extraneous wrapper section/shell) and real, visible CSS improvements to rank markers across three themes, delivering tangible, lasting user-facing value.
A adds a real architectural seam (RouteContext wrapping ThreadNav with item_href/thread_url APIs) plus a concrete ItemId migration plan that steers lasting identity/routing work. B only unwraps a vote-compare-shell div and restyles ranking-list counters in CSS—cosmetic HTML/theme churn with little structural impact.
Side A introduces a new `RouteContext` abstraction in `server/src/html/routing.rs`, re-exports it, and documents a concrete migration path toward centralized, scope-aware URL generation, creating an architectural seam that future code can build on. Side B is primarily a UI refactor that removes a wrapper element in the vote-compare template and adjusts CSS styling for ranked lists, improving presentation but not changing core behavior or architecture.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_6a02ffb06a41 (tommy-mor)
Side B fixes an actual off-by-one/indexing bug (thread_post_index semantics) with real code, updated docs, and new regression tests, delivering concrete lasting value. Side A is purely a planning markdown file plus an unused RouteContext wrapper that duplicates ThreadNav without migrating any call sites, i.e., speculative scaffolding rather than executed value.
B fixes a real index/contract bug: thread_post_index becomes consistently 0-based like `/t/tag/N`, drops the silent `unwrap_or(0)`/`map(|i| i+1)` fallback, always emits post links, and locks behavior with integration tests. A mostly adds a temporary plan.md plus a thin RouteContext delegating to ThreadNav—useful scaffolding, but little completed behavior versus B’s lasting correctness.
Side B makes concrete behavioral changes: it enforces the invariant that a rank-history post must exist in `ingests_by_scope_thread` with `expect(...)` instead of silently falling back to `0`, aligns `thread_post_index` with the actual 0-based `/t/tag/N` routes, updates rendering to always emit the link, and adds integration tests documenting the behavior. Side A mostly introduces a planning document plus a `RouteContext` wrapper around `ThreadNav` and re-exports it, which is useful scaffolding but does not substantially change project behavior yet.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_88200cfa5c4d (tommy-mor)
Side A is a large planning markdown file plus a thin unused RouteContext wrapper that just delegates to ThreadNav—no behavioral change and largely speculative documentation for a future refactor. Side B fixes real clippy warnings, wires up a previously-dead test (missing #[test] attribute meant a test never ran), and makes small correctness/idiomatic improvements (is_some_and, irrefutable pattern cleanup, avoiding unnecessary allocations) across the codebase, providing concrete, lasting code-quality value.
A adds a concrete RouteContext API (routing.rs + export) and a detailed, actionable architecture plan for the ItemId/routing migration—foundation that steers lasting design. B is mostly mechanical clippy/style churn plus one missing #[test] attribute, with little durable product or design impact.
Side A introduces a new `RouteContext` abstraction for HTML routing, exports it from `server/src/html/mod.rs`, and adds a detailed migration plan describing the architectural shift from string-based `CanonicalItemUrl` to structured `ItemId`. While much of the commit is planning documentation, the new routing layer creates a lasting extension point for centralizing URL generation, whereas Side B is almost entirely Clippy-driven cleanups, minor test fixes, and stylistic refactors with little effect on the project's design or functionality.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_16438843de8f (tommy-mor)
B adds concrete, potentially reusable infrastructure (Dockerfile, fly.toml, deps.edn) plus two functional modules (EventLog for JSONL persistence, ViewStore for view counting) that encapsulate real logic, even though their file placement suggests staging. A's diff is dominated by a long speculative planning document (plan.md) that will be deleted per its own text, with the only functional code being a thin RouteContext wrapper that mostly forwards to existing ThreadNav methods without yet being adopted anywhere.
B adds load-bearing runtime and ops pieces (JSONL EventLog append/load, ViewStore persistence, Dockerfile/fly.toml, kaocha deps.edn) that the project actually runs on. A mostly drops a disposable plan.md plus a thin RouteContext newtype that delegates to existing ThreadNav, so little permanent behavior lands beyond scaffolding for a future refactor.
Side B adds several concrete, reusable capabilities: an asynchronous JSONL `EventLog` with append/load logic and error handling, a persistent `ViewStore` that flushes counts to disk, plus deployment artifacts (`Dockerfile` and `fly.toml`) that enable building and running the project. Side A mostly introduces a detailed migration plan document and a thin `RouteContext` wrapper around `ThreadNav` with re-exports; while directionally useful, it is largely scaffolding and documentation rather than completed functionality.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_e57094c6229a (tommy-mor)
Side B is a real, working feature: it introduces explicit user-initiated Reddit fetch (removing implicit auto-fetch), persists full API payloads via a new EntityImported event with replay support, adds config for API bases/env-based creds, UI wiring, tests (unit + integration), and a fixture. Side A is purely a planning document plus a thin RouteContext wrapper that isn't yet adopted anywhere, offering no functional change or bugfix—mostly aspirational scaffolding.
B ships a durable entity-import path (EntityImported events, raw payload + derived view, explicit FetchEntity UI, configurable Reddit broker, replay/tests/fixtures), while A mainly adds a forward-looking plan.md and a thin RouteContext newtype that still delegates to CanonicalItemUrl/ThreadNav without finishing the migration.
Side B implements substantial new functionality: it replaces automatic Reddit fetches with explicit user-triggered imports, persists full upstream payloads via a new `EntityImported` event for replay, updates the reducer to store raw payloads plus derived views, and adds configuration, tests, and UI support for the workflow. Side A mainly adds a detailed planning document and introduces a thin `RouteContext` wrapper re-exported from the HTML module, which is useful for future work but does not materially change project behavior yet.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_b8e80699547c (tommy-mor)
Side A adds a real, integrated module (`routing.rs` with `RouteContext`) wired into `html/mod.rs` and exported for use, plus a planning doc that gives concrete direction for a large refactor. Side B drops a large standalone `reddit.rs` at the repo root with no module wiring or Cargo.toml integration shown, making it likely dead/orphaned code that doesn't demonstrably compile into the project. Side A's contribution is smaller but actually lands as usable, integrated code plus useful documentation, while Side B is unintegrated bulk.
A lands project-aligned architecture: a concrete RouteContext API wired into server HTML plus a detailed ItemId migration plan tied to existing types/reducer/routing. B adds a sizable but unintegrated root-level reddit.rs client with no crate wiring or call sites, so it is less clearly lasting product value.
Side B adds a substantial, functional `reddit.rs` implementation: a rate-limited Reddit API client, HTTP error handling, serde models for listings/posts/comments, custom deserializers, and helper methods for extracting typed data. Side A mostly introduces a planning document plus a thin `RouteContext` wrapper around `ThreadNav` that re-exports existing routing behavior, providing architectural direction but little immediate functional change.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_48aeaf9b52c3 (tommy-mor)
Side B fixes an actual algorithmic bug (bipartite/oscillating Markov chain in the ranking power-iteration) with a correct, well-justified change grounded in the cited paper, plus regression tests in both Rust and Clojure across multiple topologies. Side A is purely a planning document and a thin wrapper struct (RouteContext) that just delegates to existing ThreadNav methods without migrating any call sites, providing no functional change or real refactor yet—its value is aspirational/documentation only.
B fixes a real ranking correctness bug (star topology yielding uniform scores from bipartite oscillation) by switching to paper-correct degree-based d_max, with Rust and Clojure regression coverage. A mostly adds a forward-looking plan.md plus a thin RouteContext newtype that still delegates to ThreadNav/CanonicalItemUrl without finishing the identity refactor.
Side B fixes a real correctness bug in `server/src/ranking.rs` by switching the Rank Centrality transition matrix to use degree-based `d_max`, preventing oscillation and producing correct rankings for star topologies. It also adds focused Rust and Clojure regression tests with ranking fixtures, while Side A primarily adds a long design plan and a `RouteContext` wrapper around `ThreadNav` that introduces little functional change.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_92734e554a25 (tommy-mor)
Side A is a large planning document plus a thin, mostly unused wrapper struct (RouteContext) that isn't wired into call sites yet, offering speculative value. Side B makes a small but concrete fix (correcting CI node-version/npm workflow logic and removing duplicate/dead tests), which is a real, immediately useful change even though minor in scope.
A adds a concrete RouteContext abstraction plus a detailed, actionable migration plan for ItemId/routing—foundational design that steers lasting architecture. B only bumps Node in release CI and deletes two obsolete validation tests, which is useful hygiene but far smaller in project impact.
Side A introduces a new `RouteContext` abstraction in `server/src/html/routing.rs`, re-exports it, and documents a concrete migration plan toward structured `ItemId` and centralized route generation, creating a reusable architectural direction even though most call sites are not yet migrated. Side B mainly updates the GitHub Actions Node version, removes an npm upgrade step, and deletes a couple of obsolete tests, which is comparatively routine maintenance with less lasting impact on the codebase design.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_73d485b8085b (tommy-mor)
Side B ships a substantial, working feature: GitHub OAuth login, session management, pseudonym claiming, trust-weight identity events, projection/storage schema updates, route wiring, JS/UI changes, and new integration tests, plus it removes an in-tree crate in favor of a git dependency (real infra cleanup). Side A is purely a planning document plus a thin unfinished RouteContext wrapper that just delegates to existing ThreadNav methods with no call-site migration, providing far less concrete lasting value than the shipped auth system in B.
B lands a full GitHub OAuth/session/pseudonym stack, gates votes on real identity, projects PrincipalCreated/OauthLinked/PseudonymClaimed into durable maps, and extracts the in-tree durable crates to an external git dep—durable product and architecture. A mostly adds plan.md plus a thin RouteContext wrapper still delegating to ThreadNav/CanonicalItemUrl, so it stages a refactor rather than delivering lasting behavior.
Side B introduces substantive, lasting functionality: GitHub OAuth/session support, pseudonym claiming, new identity-related event types and projection logic, durable session storage, routing, UI integration, and accompanying tests. Side A mainly adds a detailed migration plan document plus a small `RouteContext` wrapper module and re-export, which is useful for future work but does not materially change project behavior.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_3403e5929da7 (tommy-mor)
Side B is a real, tested bugfix/behavior change: it changes sibling-group rendering so each unranked item forms its own group, backed by a new unit test verifying the exact grouping. Side A is purely a planning document plus a thin, unused wrapper struct (RouteContext) that duplicates existing ThreadNav methods without migrating any call sites, so it adds speculative scaffolding rather than shipped functionality.
B ships a concrete sibling-nav behavior fix (each unranked item becomes its own group) plus a focused regression test, which is lasting product logic. A mostly adds a long plan.md and a thin RouteContext wrapper around ThreadNav with no call-site migration, so it is scaffolding/docs rather than finished design or a bugfix.
Side B makes a functional change to sibling navigation by placing each unranked sibling into its own navigation group instead of combining all unranked items into one group, and it adds a regression test verifying the new grouping behavior. Side A primarily introduces a planning document and a thin `RouteContext` wrapper around `ThreadNav` with re-exports, which is useful scaffolding but does not materially change project behavior.
comparison · c_ca72f0995396 (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Side A ships a working, self-contained feature (grouped cli_panel UI with hover-to-copy, JS-injection safety assert, CSS updates) that compiles and improves real user-facing behavior across multiple call sites. Side B is almost entirely a large planning markdown document plus an unused/unwired RouteContext scaffold that duplicates ThreadNav without migrating any call sites, providing no concrete functional or architectural change yet.
A ships a complete, used feature: cli_panel becomes multi-command with row click-to-copy, JS single-quote safety asserts, call-site updates, and theme CSS—real UX and correctness in production paths. B mostly adds an ephemeral plan.md plus a thin RouteContext wrapper over ThreadNav with no call-site migration or ItemId work, so little lasting behavior landed.
Side A delivers a functional improvement by redesigning `cli_panel` to support multiple commands in one component, adding click-to-copy rows, updating all call sites, and introducing runtime assertions that prevent unsafe characters from breaking the inline single-quoted JavaScript. Side B primarily adds a planning document and a new `RouteContext` wrapper module that is re-exported but not yet integrated into behavior, so its immediate lasting impact on the project is much smaller.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_cf0a514b261a (tommy-mor)
B is a small, verified real change: it removes dead/incorrect logic in apply_vote, explains why via the add_edge_weight invariant, and updates the corresponding test to assert the new correct behavior. A is purely a planning document plus a thin, largely unused wrapper struct (RouteContext) that doesn't actually change any behavior or migrate any call sites yet, so its lasting code value is minimal compared to B's concrete bugfix.
B removes proven dead code in apply_vote and corrects the related test to match real behavior (items/pairs register; zero-weight edges stay absent), a small lasting simplification of production logic. A mostly adds a handoff plan.md plus a thin RouteContext newtype that still delegates to ThreadNav/CanonicalItemUrl—useful staging, but little durable design landed compared with B’s precise reducer cleanup.
Side B removes a redundant early return in `GroupState::apply_vote`, allowing items and voted pairs to be registered while still relying on existing zero-weight edge handling, and updates tests to verify the intended behavior. Side A mainly adds a long planning document plus a thin `RouteContext` wrapper around `ThreadNav` and exports it, which is useful scaffolding but introduces little functional change on its own.
comparison · c_d6d339485601 (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Side A adds a real, tested feature (surfacing connectivity stats in the CLI pair output) with concrete implementation and two unit tests verifying formatting behavior. Side B mostly adds a large speculative planning document (plan.md) describing future refactor work not yet done, plus a thin untested RouteContext wrapper that just delegates to ThreadNav without changing any call sites—net lasting code value is minimal compared to A's shipped, verified functionality.
A ships a complete, tested CLI feature that formats and surfaces existing connectivity stats on pair responses, giving voters lasting visibility into graph density and disconnection. B mostly adds a disposable plan.md plus a thin RouteContext wrapper around ThreadNav with no call-site migration, so it is scaffolding and process notes rather than finished design or a fix.
Side A adds a user-visible feature by exposing existing connectivity statistics in CLI pair output, including density, connectedness, pluralization, and targeted unit tests that verify both connected and disconnected cases. Side B mostly introduces a planning document and a thin `RouteContext` wrapper re-export with minimal functional behavior, laying groundwork but not substantially changing project functionality.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_c6beb77e8e71 (tommy-mor)
Side B fixes a real correctness bug (duplicate `id="entity-section"` when multiple entities render, e.g. vote-compare page) by switching to per-item data-attribute selectors, and meaningfully deduplicates markup by reusing entity_section in vote_compare_item_card plus cleans up now-redundant CSS. Side A is almost entirely a planning document (plan.md) with a thin, largely unused RouteContext wrapper that doesn't change any actual behavior yet — it's scaffolding/notes rather than a functional improvement.
B fixes real multi-entity UI/SSE behavior by replacing a single global `#entity-section` id with per-item `data-entity-section` selectors and consolidates vote-compare cards onto the shared `entity_section` path (with matching CSS cleanup). A mostly adds a temporary `plan.md` plus a thin `RouteContext` newtype still keyed on `CanonicalItemUrl`, so less lasting shipped design than B's concrete morph/target and DRY fix.
Side B makes a functional refactor that introduces per-item `data-entity-section` selectors and updates SSE/Idiomorph morph targets to use them, removing reliance on duplicate global IDs and reusing the shared `entity_section` component in the voting UI. Side A primarily adds a planning document plus a thin `RouteContext` wrapper around `ThreadNav` with no migration of existing call sites, so it contributes architectural intent more than implemented 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_7ec67b9cef2c (tommy-mor) vs c_19f4b8f10b98 (tommy-mor)
Side A adds a new RouteContext abstraction (server/src/html/routing.rs) that is wired into the module tree and provides real, reusable code for scoped href building, plus a detailed refactor plan to guide future work. Side B's 'cleaner' diff simplifies a form but also strips out error_target/form_id fields from the RPC payloads and removes the toggle/label UI, which risks regressing the check_ingest error-display behavior without clear compensating benefit.
A lands a real architectural step (RouteContext wrapper + exports) and a concrete migration plan for ItemId vs hrefs, which outlasts one UI tweak. B only trims the public new-thread form (toggle, labels, check payload fields) with no structural or correctness gain.
Side A introduces a new `RouteContext` abstraction (`server/src/html/routing.rs`) and re-exports it, creating a centralized API for building scoped HTML routes (`item_href`, `thread_url`, room/public handling) that supports future refactoring away from ad hoc URL construction. Although much of the patch is planning documentation, the code change establishes a reusable architectural boundary, whereas Side B mainly alters the forum compose UI (removing the toggle, labels, and changing placeholders/button text) without adding comparable long-term infrastructure.
comparison · c_48fcbcde8f88 (tommy-mor) vs c_7ec67b9cef2c (tommy-mor)
Side A is a real, tested refactor that de-duplicates substantial shared test logic (HTTP helpers, mock OAuth, server env, harness counters) across auth.bb, grants.bb, integration.bb, and oauth.bb, reducing duplication and improving maintainability with no behavior change. Side B is almost entirely a speculative planning document (plan.md) plus a thin, unused-by-callers RouteContext wrapper stub that doesn't migrate any call sites, representing scaffolding/intent rather than delivered value.
A finishes a real maintainability win: it deletes large duplicated copies of HTTP/OAuth/assert/build helpers from auth.bb/grants.bb/integration.bb and centralizes them in test.common and test.oauth (including multi-user mock Google, complete-registration!, slug-server-env, cargo build helper). B mainly adds a forward-looking plan.md plus a thin RouteContext wrapper around ThreadNav with no call-site migration of ItemId yet, so most lasting substance is still unfinished scaffolding.
Side A performs a substantial refactor that consolidates duplicated test infrastructure into shared utilities (`test.common` and `test.oauth`), adds reusable helpers such as `run-cargo-build-release!`, `slug-server-env`, `complete-registration!`, and parameterized mock Google behavior, and updates multiple integration test suites to use them. Side B mainly adds a planning document and introduces a thin `RouteContext` wrapper re-export without migrating call sites, so it provides architectural intent but little immediate functional value.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_a337088f57f0 (tommy-mor)
Side B delivers a working, tested improvement to the dev fixture workflow (cargo-watch integration, persistent fixture-data, port reuse, summary rebasing) plus a small real cleanup in forum.rs, all functional and immediately useful. Side A is purely a planning document (plan.md) plus a thin, mostly-unused RouteContext wrapper that still delegates to the old CanonicalItemUrl/ThreadNav internals—no actual migration or bugfix, just scaffolding and prose that may become stale.
A lands lasting architecture: a concrete RouteContext API (item_href, thread/garden/room URLs, ThreadNav interop) plus a phased ItemId migration plan that defines how identity and hrefs should evolve. B mainly improves local DX (cargo-watch fixture, persistent fixture-data/, preferred port) and removes a bit of room-page UI chrome—useful, but not structural product design.
Side B makes functional improvements to the development workflow by adding a persistent `fixture-data/` setup, reusing seeded data across runs, preferring a stable port with fallback, launching via `cargo watch`, and extending server startup handling, all of which directly improve ongoing developer iteration. Side A mostly introduces a large planning document plus a thin `RouteContext` wrapper around `ThreadNav` with re-exports, which establishes direction but contributes relatively little executable behavior beyond API scaffolding.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_9608dc0d38ab (tommy-mor)
Side B fixes a real tokio RwLock re-entrancy deadlock bug in the RPC handler, adds an integration test covering RoomCreate, and hardens babashka test infra (HTTP timeouts, log redirection to avoid pipe deadlocks) plus corrects test assertions to match actual stored username format. Side A is purely a planning document and a thin wrapper struct (RouteContext) that just delegates to existing ThreadNav methods without migrating any call sites, providing no functional change or bugfix.
B fixes a real Tokio RwLock deadlock by dropping read guards before nested lock acquires in RoomCreate/RoomGrant, plus regression coverage and test harness hang/timeout fixes. A mostly adds a planning doc and a thin RouteContext newtype that still delegates to ThreadNav/CanonicalItemUrl, so it stages work rather than landing lasting behavior.
Side B fixes a real concurrency bug by shortening the lifetime of `tokio::sync::RwLock` read guards before later `read().await`/`write().await` calls in `handle_rpc_batch`, preventing self-deadlock during room creation and grants. It also adds an integration test covering room creation and improves test infrastructure with timeouts and optional log redirection, whereas Side A mainly adds a migration plan document and a thin `RouteContext` wrapper around `ThreadNav` without changing application behavior.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_0a9a8eab32ba (tommy-mor)
Side B is a real, tested bugfix: it replaces a timestamp-based feed cutoff with an ingest-index anchor (fixing same-millisecond and clock-rollback bugs), adds room field for permission clarity, and includes substantial integration tests proving multi-user visibility correctness. Side A is purely a planning document plus a thin, mostly unused wrapper struct (RouteContext) with no behavioral change or migration completed, so it contributes intent but no delivered value yet.
B fixes real feed correctness and privacy: durable ingest-index anchors instead of millisecond timestamps, permission-aware multi-user room visibility, FeedPost.room, plus solid integration/CLI tests. A mostly adds a long future-refactor plan.md and a thin RouteContext wrapper over ThreadNav without finishing the ItemId migration, so it delivers far less lasting runtime value.
Side B implements a substantive feed correctness fix by introducing a shared `rpc_feed` path that anchors implicit catch-up to durable ingest order instead of timestamps, preserves permission filtering, adds room metadata to `FeedPost`, and includes integration tests covering timestamp collisions, private-room visibility, and revoked access. Side A mainly adds a planning document plus a thin `RouteContext` wrapper and re-export without migrating call sites or changing runtime behavior, so its lasting project impact is much smaller.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_59974b9da42a (tommy-mor)
Side B is an actual executed refactor that splits a monolithic forum.rs into focused modules (nav.rs, ingest.rs, new_thread.rs, room_members.rs, access.rs) plus a small useful debugging script, improving real code organization while preserving behavior. Side A is purely a planning document plus a thin, incomplete RouteContext wrapper that mostly just forwards to ThreadNav—useful as a roadmap but contributes no functional improvement yet and risks becoming stale/deleted per its own text.
A adds lasting architecture: a concrete RouteContext API (routing.rs + re-exports) and a detailed ItemId migration plan that defines identity vs href boundaries. B is mostly mechanical forum file-splitting plus a macOS sample-fixture helper—useful organization, but little new behavior or durable design compared with A’s scaffolding.
Side B performs a real codebase refactor by extracting forum functionality into focused modules (`access.rs`, `ingest.rs`, `nav.rs`, `new_thread.rs`, `room_members.rs`), introducing reusable components like `ThreadNav`, and moving existing UI logic without changing behavior, which improves maintainability. Side A mostly adds a detailed migration plan (`plan.md`) plus a thin `RouteContext` wrapper around `ThreadNav`; while useful as guidance, it leaves the underlying architecture largely unchanged.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_7b940fef005f (tommy-mor)
B is a concrete, functional simplification: it removes dead/unused parameters and a redundant card-render/morph path from a real, in-use handler, tightening the vote-compare success flow. A merely adds a long planning markdown document plus an unused RouteContext wrapper that isn't wired into any call site, providing speculative scaffolding rather than working improvements.
A adds a real architectural seam (RouteContext wrapping ThreadNav with item_href/thread_url APIs) plus a concrete phased ItemId migration blueprint touching types, reducer, and HTML. B only trims dead parameters and a #vote-compare-preview morph from vote_compare_post_success_js—useful cleanup, but far narrower and less structural lasting impact.
Side A introduces a new `RouteContext` abstraction with a dedicated routing module, re-exports it, and documents a concrete migration plan toward separating item identity (`ItemId`) from routing and presentation. Although much of the commit is planning documentation, it also adds reusable routing infrastructure that can support future refactoring, whereas Side B mainly removes parameters and stops updating the `#vote-compare-preview` region, simplifying an existing function without introducing comparable architectural value.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_7ca21f5e83a8 (tommy-mor)
Side A is purely a planning document plus a thin, largely unused RouteContext wrapper with no call-site migration or tests, offering speculative future value but no functioning behavior change. Side B adds a concrete, runnable browser test exercising real pool-scoped voting flow end-to-end, which provides lasting regression protection and verifies actual application behavior.
B adds an executable browser test that seeds a pool, drives the vote→next-pair loop, and asserts pool-scoped pairs and edge-history updates—lasting regression coverage of real product behavior. A mostly adds a temporary plan.md plus a thin RouteContext newtype that delegates to ThreadNav without migrating call sites or introducing ItemId, so its durable code impact is smaller.
Side B adds an executable end-to-end browser test that seeds data, exercises the `/vote?pool=~/pool` flow through repeated vote/next-pair iterations, and verifies both edge-history updates and that displayed pairs remain within the requested pool, providing ongoing regression protection. Side A mostly introduces a detailed planning document plus a thin `RouteContext` wrapper around `ThreadNav` with re-exports, which establishes direction but does not yet change routing behavior or complete the refactor.
comparison · c_7ec67b9cef2c (tommy-mor) vs c_b3cb2762569d (tommy-mor)
Side A is purely a planning document plus a thin, unused RouteContext wrapper with no call-site migration or tests exercising it. Side B ships an actual working feature (parser/parser_action/parser_render modules, wired into ui_action, HTML mod, JS, and covered by new integration and Clojure smoke tests), representing real functional code that lands and is verified, despite also containing some churn (legacy file removal, .gitignore tweak).
Side A lands a concrete RouteContext abstraction plus a precise, phased design for ItemId vs routing that targets core types and call sites; that is durable architectural leverage. Side B’s huge diff is mostly relocating the legacy reddit graph parser and wiring a demo UI around it (move + glue + tests), which is real product surface but lower lasting structural value per line than A’s design work.
Side B adds a working parser subsystem integrated into the server and UI: new parser and action/render modules, a `ParseQuery` HTML action, live client-side interactions, and integration tests verifying the new parser panel. Side A mainly introduces a detailed migration plan document plus a thin `RouteContext` wrapper around `ThreadNav` and re-exports, which is useful scaffolding but contributes far less executable functionality.