Skip to content

docs: 2.0.0 release readiness - #251

Closed
pftg wants to merge 5 commits into
masterfrom
release/2-0-0-readiness
Closed

docs: 2.0.0 release readiness#251
pftg wants to merge 5 commits into
masterfrom
release/2-0-0-readiness

Conversation

@pftg

@pftg pftg commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Audit of everything a 2.0.0 final would ship, plus the fixes that did not require touching lib/. Do not merge without reading the blocker list — two items need a decision that is not mine to make.

Version not bumped, nothing tagged, nothing published.

Blockers, ranked

1. driver: is deleted in 2.1 and 2.0 never warns about it. SnapDiff.config.driver = :vips, the legacy Capybara::Screenshot::Diff.driver = :vips, and the per-screenshot driver: override are completely silent on 2.0 and raise NoMethodError on 2.1 (#249's own body says so). driver: :auto is equally silent on any machine that has libvips — the :auto warning only fires when :auto actually falls back to ChunkyPNG. That contradicted docs/drivers.md, which promised everything 2.1 removes "warns once per process naming 2.1".

Evidence — a SnapDiff.configure block setting driver = :vips, then a comparison, produced zero output:

-- config readback: tolerance=0.0005 driver=:vips
-- compare different?=true
DONE (no warnings above == canonical path is clean)

2.0's whole justification is that publication mitigates the semver departure, so a silent removal is the one thing that should not be in it. What this PR did: documented it as silent in docs/drivers.md and docs/UPGRADING.md, and stopped the setup examples teaching driver: :vips. What is still open (needs lib/, and a decision): either add a Removal.warn_once on Config#driver= mirroring the existing shift_distance_limit= override, or — better, and lazier for users — have 2.1 keep driver= as a deprecated no-op instead of deleting it. I lean to the second: warning on the recommended configuration is noise, and a no-op setter costs one line in #249 versus a NoMethodError in everyone's test_helper.rb.

2. Bundler.require crashes when minitest is not in the bundle. lib/capybara-screenshot-diff.rb (and the new lib/snap_diff-capybara.rb) unconditionally require capybara_screenshot_diff/minitest, which does require "minitest". Any project without minitest in its Gemfile — an RSpec-only or non-Rails suite — dies at boot:

There was an error while trying to load the gem 'capybara-screenshot-diff'. (Bundler::GemRequireError)
Gem Load Error is: cannot load such file -- minitest

Pre-existing: 1.15.1 fails identically, so it is not a 2.0 regression and I did not fix it (lib/ is another lane's). But 2.0 extends it to the new gem name, and a fresh adopter following the README hits it. lib/ owner's call. Rails apps are unaffected (activesupport depends on minitest).

3. The README's quick start produces a setup that cannot compare. gem 'ruby-vips' # Optional was not true: with neither ruby-vips nor chunky_png the gem raises RuntimeError: Wrong adapter nil. Available adapters: []. Fixed in this PR (README now says the gem ships no backend and names the error).

4. Every GitHub Release so far links to a 404. release.yml pointed the release body at blob/main/CHANGELOG.md; the default branch is master. Fixed — links resolve at the tag now, which cannot drift.

5. RELEASE_PREP.md was a v1.15.1 checklist. It described neither the dual-name publish, nor trusted publishing, nor prereleases, nor what to do when a run fails after tagging. Rewritten as a runbook. CONTRIBUTING.md was worse: it pointed at lib/capybara/screenshot/diff/version.rb (which no longer holds the version, so the workflow's verify step would reject your release) and offered rake release as an alternative — which publishes only capybara-screenshot-diff and silently skips the mirror.

6. The README still teaches the API 2.1 deletes. Quick start, config examples and the compare snippet are all Capybara::Screenshot::Diff / CapybaraScreenshotDiff, so a brand-new 2.0 adopter writes code that warns immediately and breaks at 2.1. Deliberately not fixed here — it is a README rewrite, not a version sweep, and it overlaps the fresh-adopter lane. Flagging it as the largest remaining 2.0 embarrassment.

The gem-name decision

capybara-screenshot-diff is the name we tell people to install. snap_diff-capybara stays published as an identical mirror so the forward-looking name is reserved and resolvable, but nothing recommends it.

Reasoning: every existing user, badge, and third-party blog post points at the old name, so recommending the new one to newcomers buys nothing and creates the exact configuration that trips SnapDiff::DualInstallError the first time two Gemfiles merge. The mirror can become primary at 2.1, when the rename actually lands. Stated once in the README banner, with the dual-install consequence; every install snippet in the repo already agreed, so this was a framing fix rather than a sweep.

Packaged gem inventory

gem build → 93 files, 776K.

lib/ 77 files — canonical snap_diff/, legacy capybara/ + capybara_screenshot_diff/ trees, both Bundler.require entry files, the HTML report template
docs/ 12 user-facing files + 2 images
root README.md, LICENSE.txt, CHANGELOG.md
runtime deps capybara (>= 2, < 4) — correct and minimal; every image backend is an optional require
executables none (dead bindir/executables lines removed — the allow-list never matched exe/)

Removed from the package: docs/docker-testing.md (documents bin/dtest, which is not packaged). Already correctly excluded: docs/RELEASE_PREP.md, tests, CI, Rakefile, gems.rb, the gemspec. For contrast, the 1.15.1 gem shipped Rakefile, gems.rb, the gemspec and CODE_OF_CONDUCT.md, and had no README — rubygems.org showed nothing.

Added test/unit/gemspec_packaging_test.rb to pin all of the above. Verified it actually fails: unpackaging lib/snap_diff-capybara.rb turns the entry-point assertion red.

What a 1.15.1 user actually sees

Real installs on ruby 4.0.6, scratch projects outside the repo, master pulled in via path:.

Before (1.15.1), legacy test_helper.rb, legacy config block, legacy constants — clean output.

After (this master), same file, nothing changed but the Gemfile line:

[snap_diff deprecation] This process uses the v1 `Capybara::Screenshot*` / `CapybaraScreenshotDiff*` API. It still works in 2.0 and is REMOVED in 2.1 -- see docs/UPGRADING.md for the SnapDiff replacements. Silence with `SnapDiff.silence_deprecations = true` or SNAP_DIFF_SILENCE_DEPRECATIONS=1. (shown once per process)
[snap_diff deprecation] `Capybara::Screenshot::Diff::ImageCompare` is deprecated (constant); use `SnapDiff::Comparison` instead. (called from .../run.rb:16)
[snap_diff deprecation] `CapybaraScreenshotDiff::SnapManager` is deprecated (constant); use `SnapDiff::SnapManager` instead. (called from .../run.rb:16)
-- version: 2.0.0.beta3
-- legacy config readback: tolerance=0.0005 window=[1280, 1024]   # identical to 1.15.1
-- compare different?=true                                        # identical to 1.15.1
-- legacy constants: ImageCompare=SnapDiff::Comparison SnapManager=SnapDiff::SnapManager
-- assertions module: SnapDiff::Minitest::Assertions

Nothing broke. Three warnings, all actionable, all pointing at 2.1. The only surprise worth calling out is the last two lines: constants print under their SnapDiff:: names, so a CI job that string-matches the old class name in output needs updating. That is in the CHANGELOG's "five things that can actually break".

A canonical-names setup (require "snap_diff/integrations/minitest" + SnapDiff.configure) is completely silent — zero warnings.

Two more, both green: Bundler.require under gem "capybara-screenshot-diff" and under gem "snap_diff-capybara", each from its own built .gem with the mirror gemspec generated exactly the way release.yml generates it. And the dual-install guard, with both gems genuinely installed into one GEM_HOME:

SnapDiff::DualInstallError: Both `capybara-screenshot-diff` and `snap_diff-capybara` gems are installed. …

One incidental improvement worth a CHANGELOG line: 2.0 dropped the undeclared activesupport runtime requirement. 1.15.1 requires active_support/core_ext/module/attribute_accessors without declaring the dependency, so a non-Rails install fails to load. Reproduced, then confirmed master needs nothing but capybara.

Open issue sweep

Nothing blocks. #217 (fiber/thread-safety hardening) says so explicitly in its own non-goals; its "document the config contract — configure before parallelism starts" item is a cheap doc win for 2.0 if someone wants it. #166 is the v2 umbrella and should close with the release. #249 is the 2.1 draft and still needs the two human items in .ai/HANDOFF.md. Two docs sent custom-driver maintainers to #166 while a third sent them to the issue tracker; now consistent.

Still unresolved

  • Blockers 1, 2 and 6 above — all need a decision or another lane.
  • Seven stale 3.0 comments remain in lib/ (snap_diff.rb, config.rb, drivers.rb, dsl.rb, legacy_shims.rb, capybara/screenshot/diff/config_legacy.rb). Comments only, no behavior. Left alone because lib/ is another lane's; the Rakefile and docs/architecture.md copies are fixed here.
  • CHANGELOG.md's v2.0.0 heading says unreleased. The release step sets the date — docs/RELEASE_PREP.md now lists it.
  • The beta2 CHANGELOG section still contains the historically false "defined? … unchanged" claim. Left as history; the v2.0.0 entry states the real behavior, which I re-verified (const_defined? is false for lazily shimmed names).

Gates

rake test:unit 590 runs / 0 failures · rake test:canonical 487 / 0 · rake test 618 / 0 (1 pre-existing skip, unchanged from master) · standardrb clean (161 files) · yamllint passes. All on ruby 4.0.6. The five new runs are gemspec_packaging_test.rb.

Summary by Sourcery

Prepare the repository and release documentation for the 2.0 transitional release while validating the packaged gem and documenting remaining migration blockers.

New Features:

  • Document the 2.0 transitional release, canonical SnapDiff API, migration warnings, 2.1 removals, dual gem names, and known compatibility caveats.
  • Add guidance for accepting intentional screenshot baseline changes through committed updates.

Bug Fixes:

  • Fix GitHub Release links so changelog and upgrade-guide references resolve against the release tag.
  • Correct the quick-start documentation to require an image backend and explain the failure when none is installed.
  • Prevent contributor release instructions and non-consumer documentation from being included in packaged gems.

Enhancements:

  • Rewrite the release preparation guide as a trusted-publishing runbook covering dual-gem publication, prereleases, retries, and post-release verification.
  • Clarify the gem-name policy, upgrade path, backend requirements, deprecations, packaging behavior, and canonical documentation.
  • Update release and architecture references to reflect the 2.1 compatibility split and current version source.

Deployment:

  • Document and align the release workflow with publishing both gem names through trusted publishing and creating tag-specific GitHub Release links.

Documentation:

  • Expand the 2.0 changelog and upgrade documentation with migration guidance, compatibility breaks, deprecation behavior, known limitations, and rollback instructions.

Tests:

  • Add gemspec packaging tests covering both Bundler entry points, required consumer files, excluded contributor files, and runtime dependencies.

Chores:

  • Refresh gem metadata and package allow-list to describe the project accurately and exclude build-only files and documentation.

Audit of everything a 2.0.0 final would ship, and the fixes that did not
need lib/ changes.

CHANGELOG
- A v2.0.0 entry written for someone upgrading from 1.15.1, not a diff of
  the betas. What to change (the version), what they will see (exact
  warning text), the five things that can actually break, and what 2.1
  removes. Every claim verified against a real install; the beta sections
  stay as history.

Version consistency
- README, docs/UPGRADING.md: no more "beta"/"alpha"/"experiment" framing
  and no beta pins. Gemfile examples say `~> 2.0`.
- Gem name: `capybara-screenshot-diff` is the one we tell people to
  install; `snap_diff-capybara` is a reserved identical mirror. Stated
  once in the README with the dual-install consequence, applied
  everywhere else.
- Stale "3.0" references in the Rakefile and docs/architecture.md are now
  2.1 (#247 fixed the user docs and missed these).

Corrections to claims that were not true
- docs/drivers.md promised that everything 2.1 removes "warns once per
  process naming 2.1". `driver: :auto` is silent whenever ruby-vips is
  present, and the `driver:` setting itself never warns at all even
  though 2.1 deletes it (`NoMethodError`). Both are now written down as
  silent, in drivers.md and UPGRADING.md, since a note is the only notice
  they can get.
- README called ruby-vips "Optional". With neither ruby-vips nor
  chunky_png installed, comparisons raise
  `Wrong adapter nil. Available adapters: []`. Says so now.
- Setup examples no longer teach `driver: :vips`, a line users have to
  delete for 2.1.

Gem hygiene
- gemspec: summary/description that describe what the gem does, the
  rubygems metadata links (source, changelog, bug tracker, docs), and
  docs/docker-testing.md dropped from the package (it documents
  bin/dtest, which is not packaged). Dead bindir/executables removed --
  the allow-list never matched exe/.
- README's links to CONTRIBUTING.md and docker-testing.md are absolute,
  so they resolve from inside the gem too.
- test/unit/gemspec_packaging_test.rb pins the packaged file list: both
  Bundler.require entry files present (this broke twice), consumer docs
  in, contributor docs and build files out, capybara the only runtime
  dependency. Verified it fails when an entry file is unpackaged.
- *.gem is gitignored.

Release process
- The GitHub Release body linked to blob/main on a repo whose default
  branch is master -- 404 on every release so far. Links to the tag now.
- docs/RELEASE_PREP.md was a stale v1.15.1 checklist. It is now a runbook
  for how releases actually happen: what the workflow does step by step,
  the trusted-publisher prerequisite for BOTH gem names, prereleases,
  post-release verification, and what to do when a run fails halfway.
- CONTRIBUTING.md pointed at the wrong version.rb and recommended
  `rake release`, which publishes only one of the two gem names.

Verified with real installs on ruby 4.0.6: 1.15.1 -> this master via
path:, a canonical-names setup, `Bundler.require` under each gem name
from the built .gem, and the dual-install guard with both gems installed.

No lib/ changes. Version not bumped.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @pftg, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Aug 24, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 37 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: be3f852b-801c-4067-92dc-94d9026bfe36

📥 Commits

Reviewing files that changed from the base of the PR and between 1cd89c9 and 37b1f80.

📒 Files selected for processing (14)
  • .github/workflows/release.yml
  • .gitignore
  • CHANGELOG.md
  • CONTRIBUTING.md
  • README.md
  • Rakefile
  • capybara-screenshot-diff.gemspec
  • docs/RELEASE_PREP.md
  • docs/UPGRADING.md
  • docs/architecture.md
  • docs/drivers.md
  • docs/migration-guide.md
  • docs/snapdiff.md
  • test/unit/gemspec_packaging_test.rb

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@sourcery-ai

sourcery-ai Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Docs and packaging updates to make 2.0.0 ready for final release: clarify transitional nature and 2.1 removals, document dual-gem naming and deprecations, fix release workflow links, tighten gemspec allow-list and metadata, add tests for packaged contents, and update contributor/release runbooks and driver docs (including silent driver removal).

Flow diagram for the dual-gem release pipeline

flowchart LR
    Maintainer["Maintainer dispatches release workflow"] --> Verify["Verify version and run unit tests"]
    Verify --> Tag["Create or reuse v<version> tag"]
    Tag --> PublishPrimary["Publish capybara-screenshot-diff"]
    PublishPrimary --> PublishMirror["Build and publish snap_diff-capybara mirror"]
    PublishMirror --> Release["Create GitHub Release with tag-pinned docs links"]
Loading

File-Level Changes

Change Details Files
GitHub release workflow now links CHANGELOG and upgrade guide at the tagged version instead of the main branch.
  • Update CHANGELOG link in release body to use the v tag path
  • Update docs/UPGRADING.md link in release body to use the v tag path
.github/workflows/release.yml
CHANGELOG gains a full v2.0.0 "transitional release" entry that explains behavior, migration, and actual breaking cases.
  • Add detailed v2.0.0 unreleased section describing transitional role of 2.0 and 2.1 cleanup
  • Document upgrade path from 1.15.1, deprecation behavior, and five real breaking scenarios
  • Clarify 2.1 removals, added SnapDiff namespace and config, dual-install guard, packaging changes, and fixes
CHANGELOG.md
Contributor docs and release instructions are aligned with the SnapDiff version source, dual-gem publishing, and trusted CI-based releases.
  • Update CONTRIBUTING to point version edits at lib/snap_diff/version.rb and describe the single release workflow
  • Explicitly discourage rake release and explain dual-name publishing requirements
  • Rewrite RELEASE_PREP into a CI-focused release runbook covering prerequisites, dispatch steps, and failure recovery
CONTRIBUTING.md
docs/RELEASE_PREP.md
README is updated to describe 2.0 as the transitional SnapDiff release, the 2.1 removals, and the dual gem-name strategy, plus clearer backend/installation docs.
  • Replace prerelease experiment banner with final 2.0 transitional-release description and 2.1 removal summary
  • Explain the two gem names, recommend capybara-screenshot-diff, and document DualInstallError when both are installed
  • Clarify that the gem ships no image backend and that ruby-vips or chunky_png must be added explicitly, with 2.1 implications
  • Adjust performance and installation sections to call out vips as the future-only backend and refine links to docs and contributor guides
README.md
Release-related comments in Rakefile and architecture docs are updated from a hypothetical 3.0 split to the actual 2.1 cleanup plan.
  • Retarget test/legacy deletion and canonical gate comments from 3.0 to 2.1 in Rakefile
  • Update architecture doc references from 3.0-readiness to 2.1-readiness for driver registry and legacy shims
Rakefile
docs/architecture.md
Gemspec is tightened with better metadata, an explicit runtime-dependency contract, and a file allow-list that excludes contributor-only docs and executables.
  • Refresh gem summary/description to match README positioning and visual-regression focus
  • Add Rubygems metadata links (source, changelog, issues, docs) pointing at GitHub
  • Constrain spec.files to lib/, docs/, README, LICENSE, and CHANGELOG while excluding RELEASE_PREP and docker-testing docs
  • Remove bindir/executables configuration since exe/ is not packaged
  • Assert capybara as the only runtime dependency via comments and tests
capybara-screenshot-diff.gemspec
Upgrade guide is converted from prerelease framing to a finalized 2.0 transitional guide with explicit 2.1 removals, dual-gem behavior, and driver-setting caveats.
  • Remove prerelease/alpha language and describe 2.0 as the transitional release toward 2.1
  • Recommend Gemfile pin ~> 2.0 and note snap_diff-capybara as a mirror with DualInstallError if both are installed
  • Document that driver setting (config.driver / legacy variants) is silent in 2.0 but raises NoMethodError in 2.1 and must be removed
  • Update references from issue ADR-004: Incremental migration toward SnapDiff v2 architecture #166 to the general issue tracker and adjust known caveats to non-alpha language
  • Expand the summary checklist to include reading warnings, adding ruby-vips, and dropping driver settings
docs/UPGRADING.md
Driver documentation is updated to clearly mark what 2.1 removes, which settings are silent, and what users must do on 2.0.
  • Clarify that most removals warn once per process, while driver setting and auto-with-vips are silent and only documented
  • Add explicit table rows for removal of driver setting and conditional behavior of :auto when falling back to ChunkyPNG
  • Align language around custom drivers and issue-reporting with the main issue tracker
docs/drivers.md
SnapDiff canonical API docs stop recommending config.driver and align with the 2.1 removal story and driver deprecation messaging.
  • Remove driver = :vips from SnapDiff.configure example to avoid teaching a setting that 2.1 deletes
  • Update custom-driver section to point to the general issue tracker instead of a specific issue
docs/snapdiff.md
A unit test suite is added to assert the gemspec’s packaged file list and runtime dependency contract for both gem names.
  • Load the gemspec and assert that Bundler.require entry files exist for both capybara-screenshot-diff and snap_diff-capybara
  • Verify that README, LICENSE, CHANGELOG, and key docs (UPGRADING, snapdiff) are packaged
  • Assert that contributor-only docs (RELEASE_PREP, docker-testing) are excluded from the gem
  • Ensure that only lib/docs/README/LICENSE/CHANGELOG are shipped and that capybara is the sole runtime dependency
test/unit/gemspec_packaging_test.rb
Misc doc and link hygiene: align docker-testing and contributing links with GitHub master, and clarify requirements/versions.
  • Point README’s Docker Testing link at the GitHub-hosted doc rather than the packaged gem
  • Point CONTRIBUTING link in README at GitHub master
  • Clarify README requirements for Ruby/Capybara and vips driver, including 2.1-only backend note
README.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

…ot every error it raises

docs/snapdiff.md's object map said "Base class for every error this gem
raises". It is not: a missing image backend raises a bare RuntimeError
("Wrong adapter nil. Available adapters: []", reproduced on a bundle with
neither ruby-vips nor chunky_png) and StableScreenshoter raises
ArgumentError. Verified the four defined errors -- ExpectationNotMet,
UnstableImage, WindowSizeMismatchError, DualInstallError -- do all inherit
SnapDiff::Error, so the useful half of the promise holds and is now the
one being made.
@pftg

pftg commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

One more false doc claim found while verifying the CHANGELOG, fixed in 92c80a7.

docs/snapdiff.md's object map said SnapDiff::Error is the "Base class for every error this gem raises". It is not. A bundle with neither ruby-vips nor chunky_png raises a bare RuntimeError: Wrong adapter nil. Available adapters: [] (reproduced), and StableScreenshoter raises ArgumentError. The four errors the gem definesExpectationNotMet, UnstableImage, WindowSizeMismatchError, DualInstallError — do all inherit SnapDiff::Error, so that is the promise the docs and the CHANGELOG now make.

Related lib/ observation, not fixed here: that RuntimeError is the error a fresh adopter with no image gem actually hits, and "Wrong adapter nil. Available adapters: []" does not tell them to install one. A one-line message change in SnapDiff::Utils.find_driver_class_for would pay for itself, but lib/ is another lane's.

pftg added 3 commits August 24, 2026 07:57
…e tag push

Branch protection rules do not govern tag pushes; tag protection rules
(or rulesets) do. The runbook prerequisite now names the right control.
…tting dies loudly

Both were lumped together as "raises NoMethodError on 2.1". Only the config
setting does. Per-screenshot options are a free-form hash, so on 2.1
`screenshot "index", driver: :vips` is inert and nothing tells you the line
is dead -- #249's own upgrade note spells out the split. Grep-for-it advice
added, since that is the only signal a user gets.
Second pass, from customer-persona findings. Each verified here before
acting; two of the four reported items turned out to be artifacts of the
PUBLISHED beta3 rather than of master, and are handled as such.

Baselines (the oldest bug in the tracker: #5 and #6 in 2018, #133 in 2024)
- README told users to "delete the baseline and re-run" in two places.
  It cannot work. `Vcs.checkout_vcs` (lib/snap_diff/vcs.rb:24) resolves
  every baseline with `git show HEAD:<path>`, and
  `ScreenshotMatcher#check_base_screenshot` calls it before
  `need_to_compare?` tests `base_path.exist?` -- so a committed baseline is
  fetched from HEAD no matter what the working tree says, and `rm` changes
  nothing.
- New first-class "Accepting an intentional change" section: the mechanism,
  the commit that actually accepts it, and the surprising part -- staging is
  not enough, so no local run goes green until you commit. The FAQ answer
  now says the same thing instead of the opposite.
- Deliberately does NOT document RECORD_SCREENSHOTS. It is printed by our
  own error message (screenshot_matcher.rb:73) but read nowhere in lib/;
  a separate lane is implementing it, and it should be documented once it
  works, not before.

Version pinning
- `gem "snap_diff-capybara"` unpinned installs 0.0.1 -- a placeholder whose
  entire payload is one README and zero Ruby files (verified by fetching and
  unpacking it), so the user gets an immediate LoadError. And unpinned
  `gem "capybara-screenshot-diff"` resolves to 1.15.1, not to the 2.0 the
  surrounding prose is selling. Every install instruction now pins, and the
  README says plainly that the mirror name is not the one to reach for.

CHANGELOG, all verified
- Failure messages leaked a libvips pointer struct via the comparison
  metadata; `to_h` excludes `diff_mask` since #234, which landed after the
  beta3 tag, so 2.0.0 final is the fix.
- Known limitation: fork-parallel runs write no HTML report. Workers
  accumulate assertions per process; the report is written from
  `Minitest.after_run` in the parent (integrations/minitest.rb:69), which
  never sees them. Artifacts and pass/fail are unaffected.
- A note for anyone sitting on a prerelease: beta3's deprecation channel was
  incomplete, so its silence is not evidence of being migrated.

Constants
- `Capybara::Screenshot::Os` -> `SnapDiff::Os` was in no rename table.

Gemspec
- rubygems_mfa_required. The four URI fields were added in the first commit.
@pftg

pftg commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

Second pass: customer-persona findings, verified

Every item below was re-verified here before acting. Two of the four reported defects turned out to be artifacts of the published beta3, not of master — that distinction changes the verdict, so the evidence is spelled out.

Verdict on the deprecation-window item — not a 2.0.0 blocker, but beta3 must never be recommended again

The v1-upgrader persona is completely right about what they measured, and the fix is already on master.

$ git ls-tree -r --name-only v2.0.0.beta3 -- lib/ | grep -E "removal|deprecation"
lib/snap_diff/deprecation.rb

$ git ls-tree -r --name-only origin/master -- lib/ | grep -E "removal|deprecation"
lib/snap_diff/deprecation.rb
lib/snap_diff/removal.rb

removal.rb arrived in #246, after the beta3 tag was cut. Same story for Config::SETTINGS vs MAPPING, and for Capybara::Screenshot::Os under the canonical require.

I then ran the persona's exact Stage 1 — Gemfile bumped, zero code changed, v1 require + v1 configure block + v1 settings + a comparison, no legacy constants referenced — against both trees:

published 2.0.0.beta3 this master
v1-only suite zero warnings migration notice fires, names 2.1 and docs/UPGRADING.md
Capybara::Screenshot::Os under canonical require NameError resolves to SnapDiff::Os
Config::SETTINGS NameError, MAPPING alive SETTINGS (27), MAPPING gone
driver-half removal warnings do not exist all five fire (chunky_png, :auto fallback, shift_distance_limit, Drivers.loaded/.available, include SnapDiff::Driver)

So UPGRADING.md describes master, master is what 2.0.0 final ships, and the deprecation window is intact — the doc is not lying, the published beta is stale. No doc rollback needed, and no code needs to ship that isn't already there.

It does mean something sharper: anyone sitting on a 2.0.0 prerelease has been told, by silence, that they are migrated. The CHANGELOG now carries a callout saying exactly that. Every beta pin was already removed from the docs in the first commit; this is the reason it mattered.

Gem name: yes, shipping 2.0.0 final is a prerequisite

Confirmed by fetching and unpacking it — snap_diff-capybara 0.0.1 contains one file, README.md, no lib/. Unpinned, gem "snap_diff-capybara" installs that and raises LoadError on the first require.

The decision stands and gets firmer: capybara-screenshot-diff is the name to install, and it is the only name any doc recommends. Recommending the mirror is gated on 2.0.0 final existing under it — at that point 2.0.0 > 0.0.1 and the placeholder stops being reachable, so the problem solves itself and nothing further is needed. Until then the README says plainly not to reach for it and why.

Separately: unpinned gem "capybara-screenshot-diff" resolves to 1.15.1, not the 2.0 the surrounding prose sells. Every install instruction in the repo now pins (~> 2.0) — README quick start, UPGRADING.md, migration-guide.md.

Baselines — the 2018 bug, now a first-class section

Confirmed from source, not just from the reports. Vcs.checkout_vcs (lib/snap_diff/vcs.rb:24) is git show HEAD:<path>; ScreenshotMatcher#check_base_screenshot calls it, and need_to_compare? then tests base_path.exist?. A committed baseline is fetched from HEAD regardless of the working tree, so rm accomplishes nothing — which is precisely what README:110 and README:177 told people to do.

New "Accepting an intentional change" section covering the mechanism, the commit that actually accepts the change, and the counter-intuitive part both customers hit: staging is not enough, and you cannot get a green local run until you commit. The FAQ answer now says the same thing instead of the opposite.

I deliberately did not document RECORD_SCREENSHOTS. It is printed to users by our own error message (screenshot_matcher.rb:73) and read nowhere in lib/ — only in this repo's test/ and bin/dtest. It gets documented when it works, not before. Coordinating with that lane.

I also stopped short of asserting post-run disk mechanics I could not verify without a Capybara session, so the section routes the reader through git status rather than claiming a specific automatic behaviour.

CHANGELOG additions — verified, not relayed

  • libvips pointer leak: beta3's ComparisonResult#to_h was merge!(meta); master is merge!(meta.except(:diff_mask)) (fix: message leak, dead report tests, gem packaging (3.0 readiness backlog) #234, post-tag). Since to_h is what error messages use, 2.0.0 final is the fix. Listed under Fixed.
  • Fork-parallel writes no HTML report: mechanism confirmed — workers accumulate assertions per process, the report is written from Minitest.after_run in the parent (integrations/minitest.rb:69), which never sees them. Artifacts and pass/fail unaffected. Listed under a new Known limitations heading rather than buried.
  • Capybara::Screenshot::OsSnapDiff::Os added to the rename table.
  • rubygems_mfa_required added; the four URI fields went in with the first commit.

Not applied

The unsilenceable every-run [DEPRECATION] The default activation of capybara_screenshot_diff/minitest…. Reproduced, including that SNAP_DIFF_SILENCE_DEPRECATIONS=1 does not suppress it (it is a bare Kernel#warn, not routed through Deprecation/Removal). Left out of the CHANGELOG because it is a lib/ fix owned by another lane and I will not claim a fix that has not landed. If it ships, it wants a Fixed line.

Gates

rake test:unit 590/0 · rake test:canonical 487/0 · standardrb clean. CI was green on the previous head.

@pftg

pftg commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator Author

Superseded by #257, which contains all five commits from this branch rebased onto master, plus the Quick Start rake test fix and the removal of the RECORD_SCREENSHOTS false promise from user-facing docs. Reviewing and merging there to keep WIP down.

@pftg pftg closed this Aug 24, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant