styleproof 3.21.0 → 4.0.0

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