Skip to content

v1.1.0 — the visual-diff console is stable

Choose a tag to compare

@climaa climaa released this 27 Aug 13:58
· 42 commits to main since this release
67554a1

The console is the product now. v1.0.0 drew a line under the MVP — the design system, the blog, the Storybook, the acceptance suite, the differ and the orchestrator. This tag is about the surface that reviews what the differ produces: apps/visual-diff-ui has taken 65 of the 93 commits since, and it has stopped moving.

Nothing here publishes to npm — every workspace is still private: true — so the version remains a coherence marker rather than a distribution fact. All eight manifests carry 1.1.0, not eight numbers that drift.

What changed

The visual-diff console. 17 feat, 20 fix, 10 refactor. The job system grew a lock, a streaming log, a dismissable current job and guarded mutations; the report grew tier sections, a review loop, an accessibility treatment that leads rather than trails, and a three-up viewer behind a comparison modal. Client-side JSON now parses against the same zod schemas the server answers with (#385), the four routes share one mutation guard and one containment check instead of four apiece (#358, #359), and the compare ask carries a counter so a repeat press from another tab still lands (#389).

The accept tab is gone (#356). It spawned promote, which writes a gitignored __baselines__ that no CI job reads — a review gesture that looked like it accepted a baseline and accepted nothing. Accepting now happens where it always really happened: the accept-baselines workflow a person dispatches, or accept in the pinned container. ModeTabs is two modes, capture and compare, and says why in its own header.

The accept loop closed (#330) — the Docker wrapper, accept-baselines.yml and the nightly determinism job that compare.mjs's STRICT_ENV was built for. That was the last of Wave 4's tail.

packages/ui gained the eight components the console needed — TriStateCheckbox, SegmentedControl, BucketChip, Thumbnail, Dialog with its bottom-sheet variant, Table, and the rest — taking the system to 27 in four tiers, still token-only, still layered by eslint-plugin-boundaries.

By the numbers

  • 150 test files / 2,690 tests — 790 console, 654 orchestrator, 490 ui, 334 visual-diff, 307 blog, 115 storybook
  • 42 Gherkin scenarios blocking in gate.needs, plus a one-scenario local lane that never runs in CI
  • 158 committed visual baselines, up from 106, still captured in a pinned container
  • 72 of the 94 commits since v1.0.0 carry a model co-author trailer — 236 of 284 all-time
  • 94 pull requests merged, 32 issues closed

The tag found its own bug

The first CI run of the release PR went red on a diff of version strings and markdown. GET /api/env reached dockerAvailable(), which blocks on docker info for up to three seconds, inside a unit suite whose timeout is five — latent since the endpoint was written, invisible on any laptop with a daemon running, and three of that block's four tests were equally exposed. lib/docker.ts had already declared the seam that prevents it; the suite had never set it (#396).

It is in these notes rather than quietly squashed into them because it is the argument this repo makes: a gate that only ever runs where the author sits is not a gate.

Known issues

Both are upstream, both are labelled and blocked, and neither has a workaround worth taking:

  • #68 — ESLint 10 is unreachable: eslint-config-next@16 breaks on it, two blockers deep.
  • #47 — TypeScript 7 blocked: Next cannot resolve tsconfig paths under the native compiler.

#264, the orchestrator's zero-diff-PR bug that led v1.0.0's known issues, is closed.

What's next

The project board is still the live, story-pointed roadmap. Wave 5's remaining work is three items, all verified still open at this tag rather than assumed: ds-table's card layout has not taken #302's measured auto-fit grid, the runner suite's confinement guard can still be answered by a turbo cache replay, and .fallow/churn.bin is tracked with nothing ignoring it.