styleproof 3.21.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,155 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [4.0.1] - 2026-07-07
11
+
12
+ ### Fixed
13
+
14
+ - **Unset capture specs no longer inflate Playwright's skipped-test count.** When
15
+ `defineStyleMapCapture({ dir: process.env.STYLEMAP_DIR, ... })` or
16
+ `defineCrawlCapture({ dir: process.env.STYLEMAP_DIR, ... })` runs with no `dir`,
17
+ StyleProof now returns before registering generated capture tests instead of
18
+ registering one skipped test per surface. Static `expected` coverage guards still
19
+ run in the normal suite. (#215)
20
+
21
+ ## [4.0.0] - 2026-07-07
22
+
23
+ The first major since v3. Three breaking defaults make StyleProof strict out of
24
+ the box — an unapproved change **blocks**, a silently-failing data endpoint
25
+ **gates**, and a manifest-less map bundle is **refused** rather than compared on
26
+ faith. Pin `BenSheridanEdwards/StyleProof@v4` to adopt; `@v3` stays on 3.x. Each
27
+ breaking entry below carries its one-line migration.
28
+
29
+ ### Removed
30
+
31
+ - **BREAKING: a manifest-less map bundle is no longer compared — it fails with exit
32
+ `2`.** Before, a two-directory `styleproof-diff`/`styleproof-report` where a side
33
+ shipped captured maps but no `styleproof-manifest.json` (the legacy committed-map
34
+ workflow) printed a one-line stderr notice and **compared anyway** (the tolerance
35
+ added in #200). The same-environment guard can't be enforced without a manifest, so
36
+ captures from different browser builds or platforms could diff as false changes. For
37
+ **v4** that tolerance is removed: a side that ships maps with no manifest now fails
38
+ loudly with exit `2` (usage/capture error), naming the bare side(s) and the remedy —
39
+ re-capture with current StyleProof; maps without a manifest are unsupported. A dir
40
+ with _no maps at all_ is unchanged: it is "no baseline yet", still the first-adoption
41
+ review path (exit `3`), not a bare bundle. **Migration:** re-capture both sides —
42
+ `styleproof-map` for spec-driven surfaces, or `styleproof-capture` for a one-shot
43
+ design diff; both now write a `styleproof-manifest.json` into their output dir
44
+ (`styleproof-capture` previously wrote none, which would have made the design-match
45
+ flow fail under this change — it now stamps one, degrading the git SHA/dirty fields
46
+ gracefully when run outside a git repo).
47
+
48
+ ### Changed
49
+
50
+ - **BREAKING: `dataResidue` now defaults to `'gate'` instead of `'warn'`.** A
51
+ data-boundary request (`replayUrl`, default `**/api/**`) that fails during a
52
+ spec-driven capture means the endpoint's _fallback_ branch shipped as the certified
53
+ state — its response-driven states were never captured. Warn-only was the
54
+ backwards-compatible launch choice, not the correct one; the default is now to BLOCK.
55
+ `'warn'` remains fully supported as the explicit opt-out (record + warn without
56
+ gating); the acknowledgement ledger and stale-acknowledgement rot protection are
57
+ unchanged. **Migration:** if a capture now fails on a data endpoint you expect to be
58
+ down, either acknowledge the intentional failures in `styleproof.data-residue.json`
59
+ (`{"<surface·endpoint>": "why"}`), or set `dataResidue: 'warn'` in the capture spec to
60
+ restore the previous non-gating behaviour. A capture with no failing data request is
61
+ unaffected. (#205)
62
+
63
+ - **BREAKING: `blocking` now defaults to `true`.** In review-gate mode
64
+ (`require-approval: true`), an **unapproved** visual change now **fails the
65
+ report job** (red ✗) out of the box, so the check blocks a merge even on a repo
66
+ without a branch-protection rule requiring the `StyleProof` status (which needs
67
+ GitHub Pro or a public repo). Previously the default was `false` — advisory-only,
68
+ where only the commit status went red. The approve→re-run flow is unchanged: tick
69
+ **Approve all changes**, re-run the job, and the re-run sees the sign-off and
70
+ passes. Certify mode (`fail-on-diff: true`) is unaffected. **Migration:** to keep
71
+ the old advisory-only behaviour, set `"blocking": false` in
72
+ `styleproof.config.json` at your repo root.
73
+ - **Pre-push guidance no longer commits maps to the PR branch** (docs and repo
74
+ hygiene only; no change to the published package, CLI, or Action). The
75
+ pre-push recipe previously ended with `git add stylemaps` + a map commit on
76
+ the branch — so maps appeared as changed files in every PR, and because all
77
+ PRs wrote the same `stylemaps/` paths, each merge forced every other open PR
78
+ to rebase. The recipe now captures and publishes to the SHA-keyed
79
+ `styleproof-maps` store branch (what `styleproof-map` already does outside
80
+ CI) and never touches the PR branch; `stylemaps/` is gitignored as a
81
+ guardrail, and the README states the maps-never-in-PR rule explicitly.
82
+
83
+ ### Added
84
+
85
+ - **Data-residue guard — a capture that embeds an unprovoked data-fault state now
86
+ says so.** During a spec-driven capture, any request matching the data boundary
87
+ (`replayUrl`, default `**/api/**`) that FAILS — a network error, or a 4xx/5xx —
88
+ means the captured state rendered that endpoint's _fallback_ branch, so the states
89
+ its real responses would drive are uncaptured and unproven (the failure mode
90
+ documented in #202). StyleProof now names each such failure on stderr at capture
91
+ time (what failed, what it means, what to do: fixture it via `page.route`/
92
+ `liveStates`, or acknowledge it), records it on the capture (`StyleMap.dataResidue`),
93
+ and surfaces it in `styleproof-diff` and the report's certification block. **Gate by
94
+ default:** an _unacknowledged_ failing endpoint blocks the diff (exit 1); acknowledge
95
+ intentional ones in `styleproof.data-residue.json` (`key → reason`), and a stale
96
+ acknowledgement (the endpoint no longer fails) also fails so the ledger can't rot — the
97
+ same discipline as `exclude` and the inventory guard. Set `dataResidue: 'warn'` to opt
98
+ down to record-and-warn without gating. A 2xx endpoint that merely wasn't fixtured is
99
+ **never** flagged (recording mode legitimately records live responses). `--json` gains
100
+ an additive optional `dataResidue` field. A capture with no failing data request is
101
+ byte-identical whichever mode you run. Fixes #205.
102
+ - **`styleproof-init` now installs the pre-push publish hook by default.** The
103
+ capture-locally/publish-to-store flow is the out-of-the-box path, not an
104
+ opt-in recipe: init scaffolds a `pre-push` hook (into `.husky/` when present,
105
+ else `.githooks/` with a one-line activation hint) that runs `styleproof-map`
106
+ — capture this commit, publish the bundle to the SHA-keyed `styleproof-maps`
107
+ branch — plus an advisory `styleproof-diff`, so CI restores by SHA and stays
108
+ report-only. `STYLEPROOF_SKIP_CAPTURE=1 git push` skips a push that can't
109
+ affect render. Never overwrites an existing hook; maps never get committed
110
+ to the PR branch.
111
+ - **`styleproof-init` now installs the approval workflow.** The generated report
112
+ workflow runs with `require-approval: true`, but the `issue_comment` handler
113
+ that flips the `StyleProof` status when a reviewer ticks **Approve all changes**
114
+ previously had to be copied from `example/` by hand — leaving the review gate
115
+ inert until someone did. `styleproof-init` now scaffolds
116
+ `.github/workflows/styleproof-approve.yml` alongside the report workflow
117
+ (copied verbatim from the packaged example, never overwriting an existing file),
118
+ so the gate is complete out of the box. It activates once the init PR merges,
119
+ since GitHub runs `issue_comment` workflows only from the default branch.
120
+ - **Enforced quality gates and an agent context layer** (repository tooling only;
121
+ no change to the published package, CLI, or Action). A `commit-msg` commitlint
122
+ hook and PR-title/body validation enforce Conventional Commits; gitleaks
123
+ (staged-diff hook + full-history CI, fail-closed), CodeQL, and
124
+ `npm audit --audit-level=high` add secret/SAST/dependency scanning; a machine
125
+ `pull_request` check validates the PR template shape. `AGENTS.md` is now the
126
+ tool-agnostic source of truth (previously a symlink to `CLAUDE.md`, now a thin
127
+ vendor adapter), with `.agents/project/` documenting architecture, conventions,
128
+ tech stack, glossary, the gate matrix, PR quality, and the Definition of Done
129
+ (moved from `.agents/DEFINITION_OF_DONE.md`). Adds `.agents/decisions/` ADRs, a
130
+ root `TODO.md`, and a `.claude/` PreToolUse hook that blocks `--no-verify`.
131
+
132
+ ### Docs
133
+
134
+ - **README catches up with the shipped gates.** A new _What a green certifies_
135
+ section surfaces the coverage, determinism, and inventory verdicts (3.9–3.14)
136
+ that previously lived only in the CLI reference bullet, linking
137
+ `docs/what-it-catches.md` and `docs/inventory-guard.md`; `styleproof-capture`
138
+ joins the CLI reference (with `--until-covered`); the policy table gains
139
+ `gateInventoryRemovals`; and the layout-equivalent-margin wording reflects the
140
+ one-sided-imbalance fix below. The repo's Claude Code skills
141
+ (`.claude/skills/styleproof*`) are fact-checked against the current CLI/API
142
+ surface: dead cross-references removed; the gate-contract exit codes, crawl
143
+ `expected` guard, browser-build compatibility key, and ledger verdicts added.
144
+
145
+ ### Fixed
146
+
147
+ - **A two-directory `styleproof-diff`/`styleproof-report` no longer skips the
148
+ same-environment guard in silence.** The guard (`assertCompatibleMapDirs`) compares
149
+ platform/arch/node/Playwright/browser-build across both maps, but no-ops when either
150
+ side carries no `styleproof-manifest.json` — so a committed-map workflow that ships
151
+ maps but no manifest (exactly the flow most likely to compare captures across
152
+ machines) got zero protection with nothing said. Both CLIs now print a one-line
153
+ notice to stderr naming the bare side(s) — `before`, `after`, or `both` — pointing
154
+ at `styleproof-map` to record a manifest, then compare anyway. It is a notice, not a
155
+ failure: **exit codes are byte-identical** (plenty of legitimate manifest-less flows
156
+ exist, e.g. `styleproof-capture` one-shots), and a pair where both sides carry a
157
+ manifest behaves exactly as before, silently. `--json` is unchanged.
158
+
10
159
  ## [3.21.0] - 2026-07-07
11
160
 
12
161
  ### Added