@codacy/verity-cli 0.32.0 → 0.32.1-experimental.f2cf829

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.
Files changed (3) hide show
  1. package/CHANGELOG.md +232 -52
  2. package/bin/verity.js +782 -359
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -5,6 +5,10 @@ All notable changes to Verity are documented here. This project follows
5
5
 
6
6
  ## [Unreleased]
7
7
 
8
+ <!-- Shipped in 0.31.2 – 0.32.0 but deliberately not announced yet: the plugin
9
+ lane is being closed-loop tested first (Road to 1.0 · Phase 2.6). Cut it
10
+ into its own heading when it is ready to be announced. -->
11
+
8
12
  **Verity ships as a Claude Code plugin.** `/plugin marketplace add codacy/verity`
9
13
  then `/plugin install verity@codacy` gives a working gate with nothing else to
10
14
  install — the plugin carries the CLI as a pinned dependency, and Claude Code
@@ -24,16 +28,6 @@ installs and updates it for you.
24
28
  plugin is present it owns the hooks, and the settings.json copy stands down.
25
29
  `verity init` detects the plugin and removes the duplicate wiring.
26
30
 
27
- ### 🚪 A project that was never set up is left alone
28
-
29
- Every hook now asks the same question the same way. `verity analyze` used to run
30
- in a project that had never seen `verity init`, create `.verity/` there, and then —
31
- with no baseline to compare against — review nothing. It now stands down like the
32
- other hooks always have, so installing Verity no longer scatters state through
33
- directories you merely opened. On the first session in such a project, Claude is
34
- told once that the gate is off here and can offer `/verity:setup` (or `verity init`
35
- on an npm install). Works correctly from linked git worktrees.
36
-
37
31
  ### ⚙️ Git-moment gating moved into the project
38
32
 
39
33
  `verity guard` now reads `.verity/config.json` instead of taking its moments from
@@ -42,7 +36,137 @@ default gates nothing** — set it with `verity config git-moments commit,push`,
42
36
  answer the question in `verity init`. An explicit `--on` still wins, so existing
43
37
  installs are untouched.
44
38
 
45
- ### 🎯 Setup finishes in one command
39
+ ### 🔧 Plugin fixes
40
+
41
+ - **Uninstalling the plugin left projects with no gate at all.** Whether the
42
+ plugin owned a project's hooks was decided by whether its install directory
43
+ existed on disk — and that directory survives an uninstall. Every project the
44
+ plugin had ever run in went on standing its own hooks down for a plugin that
45
+ was gone. Ownership now comes from Claude Code's install registry, and
46
+ `verity init` clears the stale marker.
47
+ - **A repository can no longer switch the gate off by shipping a file.**
48
+ Ownership was claimed by `.verity/.plugin-active`, a file inside the project,
49
+ and one naming any directory that happened to exist disabled every hook there.
50
+ An install Claude Code cannot vouch for is ignored.
51
+ - **A plugin installed from a local marketplace directory is recognised.**
52
+ Claude Code runs a marketplace served from a directory out of that directory
53
+ while recording the cache copy it made, so the two paths disagreed and a live,
54
+ gating install read as unverified — every reporter then said "no analysis
55
+ moment is active" about a project the plugin was gating on every turn.
56
+ - **`verity init` knows the plugin is here, and says so before it acts.** It
57
+ does two opposite things depending on that answer — write this project's own
58
+ hooks, or leave them to the plugin — and it used to choose silently. It now
59
+ names the install it found and the division of labour, and `--no-plugin`
60
+ overrules it. It detects a plugin in a project the plugin has never set up,
61
+ which is the ordinary case for someone whose first Verity install *is* the
62
+ plugin.
63
+
64
+
65
+ ## [0.32.1] — 2026-09-09
66
+
67
+ **The gate said it was on while it wasn't.** Every fix here is the same failure
68
+ seen from a different side: Verity reported itself wired and watching, and the
69
+ commit went through unreviewed. Two of them were shipped by 0.32.0 itself.
70
+
71
+ ```bash
72
+ npm install -g @codacy/verity-cli # binary only — no re-run of init needed
73
+ ```
74
+
75
+ ### 🔒 The gate is on when it says it is
76
+
77
+ - **Typing `2,3` at the setup question left you with no git gate.** The review
78
+ moments used to be answered by number — `2,3` *was* the answer — and 0.32.0's
79
+ arrow-key rewrite kept the digit shortcut on the single-select question and
80
+ lost it on this one. A digit moved the cursor without ticking anything, the
81
+ comma was ignored, and Enter then confirmed the untouched default. You got
82
+ `stop` alone: no pre-commit hook was wired, and the git gate silently did not
83
+ exist. Reported from the field as *"pre-commit hooks are not added any more"*.
84
+ A digit toggles again, and the prompt's own legend now names the keys it
85
+ accepts.
86
+ - **`git add … && git commit` was never reviewed.** The hook runs *before* the
87
+ command, so the index it inspected had not had the `add` applied yet: nothing
88
+ staged, and the gate took its "nothing to review" exit — a silent allow, with
89
+ no trace that a commit had gone unreviewed. It is the shape an agent writes by
90
+ default, so it was most of the commit gate's coverage. The gate now works out
91
+ what the command is about to stage, using git's own pathspec matching, and
92
+ understands `git commit -a` and `git commit <paths>`. Where it genuinely
93
+ cannot — a pathspec the shell expands before git sees it, an interactive
94
+ `git add -p` — it says so and lets the commit through **loudly**, rather than
95
+ reviewing a set it guessed at.
96
+ - **A verdict the CLI does not understand is no longer drawn as a pass.** An
97
+ absent or unrecognised gate decision — a truncated response, a proxy error
98
+ page — reached the `✓ PASS` line. It is reported as unreviewed.
99
+ - **`verity hooks install --moments <typo>` no longer removes every gate.**
100
+ Unrecognised moments were dropped in silence, so a single misspelling
101
+ reconciled the hooks down to nothing and printed success. It is an error now;
102
+ `--moments none` is still the way to turn them off on purpose.
103
+ - **`verity init` no longer overwrites the moments you chose.** Re-running init
104
+ to heal a config replaced an answer you had set with `verity config
105
+ git-moments`, substituting the shipped default. Your answer is now recorded
106
+ as yours, kept, and named when init keeps it.
107
+ - **A linked worktree gates what the main checkout gates.** `.verity/` is
108
+ gitignored, so a fresh `git worktree add` had no configuration of its own and
109
+ the guard there gated nothing while `verity hooks check` reported it wired. A
110
+ worktree's own `.verity/config.json` still wins when it has one — including an
111
+ explicit `none` — and `hooks check` names the file it inherited from.
112
+ - **`verity status`, `verity doctor` and `verity hooks check` answer from one
113
+ place.** They could disagree about whether a hook was wired, and two of them
114
+ were wrong from a subdirectory.
115
+
116
+ ### 🔧 Fixed
117
+
118
+ - `verity status --limit` rejects a value that is not a number instead of
119
+ quietly ignoring it.
120
+
121
+ ### Migrating
122
+
123
+ Upgrading the binary is enough for six of the seven — but not for the moments
124
+ question. If you set this project up **on 0.32.0** and answered that question by
125
+ typing numbers, the gates you asked for were never recorded, and a new binary
126
+ cannot know what you meant. Check and repair in one command each:
127
+
128
+ ```bash
129
+ verity status # Moments: is pre-commit / pre-push listed?
130
+ verity config git-moments commit,push # set what you meant; init now keeps it
131
+ ```
132
+
133
+ Projects set up before 0.32.0, or set up with the arrow keys, are unaffected.
134
+
135
+
136
+ ## [0.32.0] — 2026-09-08
137
+
138
+ **Setup takes seconds, not minutes — and the reviewer sees more than the diff.**
139
+ Installing Verity used to be two steps: `verity init`, then a Claude Code
140
+ session for `/verity-setup` to write your Standard, which took minutes and was
141
+ the step people skipped. It is now one command that takes seconds: `init`
142
+ builds the Standard from your codebase, or downloads the one your team already
143
+ registered. On the other side, the reviewer stops judging a change in a vacuum:
144
+ it sees the callers, tests and contracts around what you touched, and it can
145
+ only block on things it actually has evidence for. This entry folds in
146
+ 0.31.2 and 0.31.4, which shipped without their own headings; 0.31.3 and 0.31.1
147
+ are below.
148
+
149
+ ```bash
150
+ npm install -g @codacy/verity-cli
151
+ verity init # re-run in existing projects: heals the config, records your answers
152
+ ```
153
+
154
+ ### ⚡ One command, no second step
155
+
156
+ - **`verity init` finishes the whole job.** It used to stop halfway and hand you
157
+ off to `/verity-setup` in Claude Code to synthesize the Standard — a model
158
+ turn that took minutes, needed a session open, and was easy to skip. `init`
159
+ now does it on its own, in seconds, and the gate is live on your next session.
160
+ `/verity-setup` still exists but is optional: it is for adding
161
+ project-specific rules on top, not for getting started.
162
+ - **If your team already has a Standard, it comes down from the cloud.** Any
163
+ repository registered before — by a teammate, by you on another machine, by
164
+ CI — already has its Standard on Verity, and `init` fetches it and writes the
165
+ team's configuration to disk (when you are signed in). Cloning a repo that
166
+ already uses Verity is: install, `init`, done.
167
+ - **If nobody has one yet, `init` derives it** from the codebase — see below.
168
+
169
+ ### 🎯 `init` derives the Standard when there is nothing to adopt
46
170
 
47
171
  - **`verity init` now derives the Standard itself.** When the service has nothing
48
172
  for this repository, the CLI reads the codebase — languages counted, frameworks
@@ -111,30 +235,6 @@ rule list degrades into a filter over it (VRT-108); Semgrep's ids are deliberate
111
235
  not derived yet, so the tool is dropped rather than configured empty. Every one of
112
236
  those is now an assertion.
113
237
 
114
- ### ⌨️ The setup questions answer to arrow keys
115
-
116
- - **`verity init` no longer asks you to type a number.** Analysis intensity and
117
- the review moments are arrow-key lists: `↑↓` to move, `space` to toggle a
118
- moment, `enter` to confirm — with the recommended answer already under the
119
- cursor and the default set already ticked, so **Enter alone still gives exactly
120
- what it gave before**.
121
- - **Digits still work.** This prompt used to be "type a number", and muscle memory
122
- should not be punished for an interface improvement — a digit moves the cursor
123
- rather than confirming, so it composes with the arrows instead of being a
124
- second, hidden way to answer. `j`/`k` move too.
125
- - **An empty moment selection is refused, not accepted.** Unticking everything and
126
- pressing Enter says so instead of installing a review tool that reviews nothing
127
- — the same invariant the typed prompt held by falling back.
128
- - **Three rungs of degradation, same default at each.** Arrow keys on a real
129
- terminal; the typed number prompt when the terminal cannot do raw mode; the
130
- default when there is no terminal at all or stdin ends. An interface improvement
131
- must not become a new way for a setup to get stuck — CI, pipes and agent Bash
132
- calls behave exactly as before.
133
- - **The terminal is restored on every exit,** including Ctrl+C, which restores
134
- before exiting: raw mode left on outlives the process and makes the user's next
135
- shell prompt unusable.
136
-
137
-
138
238
  ### 🤝 Joining a project that already has a Standard
139
239
 
140
240
  - **`verity init` now offers the Standard the service already holds** for this
@@ -163,20 +263,28 @@ those is now an assertion.
163
263
  silent-forever failure: decline on Monday meaning to synthesize later, forget,
164
264
  and every later run stays quiet while the project has no local config at all.
165
265
 
166
- ### 🔧 Fixed
167
-
168
- - **An upgrade no longer removes the gates you chose.** `.verity/setup.json` only
169
- exists from this release, so every project configured before it had no recorded
170
- answer — including everyone who picked commit/push gates through the old
171
- `/verity-setup`. The first upgraded `verity init` fell back to the shipped
172
- default and reconciled those gates away, turning Stop back on. What you chose is
173
- still legible in `.claude/settings.json`, so init reads it.
174
- - `verity doctor` names the artifact that is actually missing instead of telling
175
- you to run a phase that will decline: with a Standard adopted and no analysis
176
- config, `/verity-setup` would have answered "already configured".
177
- - The setup skill learned the same case — Standard present, analysis config
178
- missing — and writes only the config rather than re-synthesizing the Standard.
266
+ ### ⌨️ The setup questions answer to arrow keys
179
267
 
268
+ - **`verity init` no longer asks you to type a number.** Analysis intensity and
269
+ the review moments are arrow-key lists: `↑↓` to move, `space` to toggle a
270
+ moment, `enter` to confirm — with the recommended answer already under the
271
+ cursor and the default set already ticked, so **Enter alone still gives exactly
272
+ what it gave before**.
273
+ - **Digits still work.** This prompt used to be "type a number", and muscle memory
274
+ should not be punished for an interface improvement — a digit moves the cursor
275
+ rather than confirming, so it composes with the arrows instead of being a
276
+ second, hidden way to answer. `j`/`k` move too.
277
+ - **An empty moment selection is refused, not accepted.** Unticking everything and
278
+ pressing Enter says so instead of installing a review tool that reviews nothing
279
+ — the same invariant the typed prompt held by falling back.
280
+ - **Three rungs of degradation, same default at each.** Arrow keys on a real
281
+ terminal; the typed number prompt when the terminal cannot do raw mode; the
282
+ default when there is no terminal at all or stdin ends. An interface improvement
283
+ must not become a new way for a setup to get stuck — CI, pipes and agent Bash
284
+ calls behave exactly as before.
285
+ - **The terminal is restored on every exit,** including Ctrl+C, which restores
286
+ before exiting: raw mode left on outlives the process and makes the user's next
287
+ shell prompt unusable.
180
288
 
181
289
  **Setup is one command.** `verity init` and `/verity-setup` were two half-flows
182
290
  that overlapped — and the overlap was not harmless: init wired the Stop hook,
@@ -189,10 +297,11 @@ with one entry point.
189
297
  - **It asks the questions whose answers it acts on** — analysis intensity, when
190
298
  to review (on stop / before commit / before push), and cost & usage telemetry.
191
299
  On the terminal, before anything is wired to them.
192
- - **Then it hands off to Claude Code** to finish the half that needs a model:
193
- reading the codebase and synthesizing the Standard (`/verity-setup`). If Claude
194
- Code isn't installed, or you are already inside a session, it prints the one
195
- command instead. `verity setup` is an alias for the same command.
300
+ - **Then it finishes the Standard itself** (adopted from the service or derived
301
+ from the codebase see above). Handing off to Claude Code for `/verity-setup`
302
+ survives only as the fallback when neither produced one, and if you are
303
+ already inside a session it prints the one command instead. `verity setup` is
304
+ an alias for the same command.
196
305
  - **`--yes` takes every recommended answer and asks nothing** (CI, scripts,
197
306
  agents) — including the GitHub login, whose unattended answer is skip, so the
198
307
  project stays local-only until you run `verity login`. `--no-setup` stops after
@@ -253,6 +362,77 @@ with one entry point.
253
362
  terminal (Ctrl+D, a pty that ends) falls back to the default instead of
254
363
  crashing init between copying the skills and wiring the hooks.
255
364
 
365
+ ### 🚪 A project that was never set up is left alone
366
+
367
+ Every hook now asks the same question the same way. `verity analyze` used to run
368
+ in a project that had never seen `verity init`, create `.verity/` there, and then —
369
+ with no baseline to compare against — review nothing. It now stands down like the
370
+ other hooks always have, so installing Verity no longer scatters state through
371
+ directories you merely opened. On the first session in such a project, Claude is
372
+ told once that the gate is off here and can offer to run `verity init`. Works
373
+ correctly from linked git worktrees.
374
+
375
+ ### 🔭 The reviewer sees the neighborhood
376
+
377
+ Measured on real commits: every change had at least one caller outside the
378
+ diff (median five), and more than half had a test referencing a changed symbol.
379
+ Verity sent none of it. Now it does — server-side, so it reached every
380
+ installed CLI on deploy day:
381
+
382
+ - **Context is what the agent actually read.** The files sent alongside your
383
+ change are the ones the agent opened this task — not the ten most recently
384
+ touched files in the repo, which is what it was.
385
+ - **Call sites of changed symbols**, one line each — including callers of a
386
+ function whose body you edited but whose name isn't in the diff.
387
+ - **At commit and push, full excerpts.** Contracts first (interfaces your change
388
+ implements), then tests, then callers, with real line numbers so the reviewer
389
+ can cite them.
390
+ - **Findings stay anchored on your change.** A problem your edit causes at a
391
+ call site is reported against the file you changed. A pre-existing problem in
392
+ a file Verity only glanced at is out of scope and cannot block you.
393
+ - **Every run says whether this fired**, and why not when it didn't (no tool, no
394
+ diff, no symbols, no sites, timeout) — in the evidence log and the guard's
395
+ coverage block. "Never fires" and "not deployed" can no longer look the same.
396
+ - Fixed on the way: the Stop-hook review was running at half its intended file
397
+ budget (20 files, not 40), and context files reached the reviewer without the
398
+ line numbers the prompt promised.
399
+
400
+ ### ⚖️ The gate only blocks on evidence it has
401
+
402
+ Raised from a customer's production runs: 134 of 655 runs blocked, and only a
403
+ third of those blocks cited a line of production source. Two things decide
404
+ whether a finding blocks — how bad *this instance* is, and what *kind* of rule
405
+ it is — and both were owned by the wrong party.
406
+
407
+ - **Severity is the reviewer's.** It used to be overwritten with the Standard's
408
+ per-pattern constant, so a finding the reviewer rated `low` (*"appears to be a
409
+ fixture value"*) blocked as `critical`. The reviewer's judgement now stands.
410
+ - **Category comes from your Standard.** It used to be a label the model
411
+ re-picked every run — the same pattern landed as `security` on one run and
412
+ `quality` on the next, and at `high` that label *is* the block. It is now
413
+ derived from where the pattern sits in your Standard. Note the direction: for
414
+ patterns you declared under security, every high instance now blocks where the
415
+ coin flip previously let some through.
416
+ - **A secrets finding needs a witness.** `no-hardcoded-secrets` blocks only when
417
+ a static tool saw it too, not on the model's word alone.
418
+ - **`exclude_paths` in your Standard actually excludes now.** It was advertised
419
+ and read by nothing.
420
+
421
+ ### 🔧 Fixed
422
+
423
+ - **An upgrade no longer removes the gates you chose.** `.verity/setup.json` only
424
+ exists from this release, so every project configured before it had no recorded
425
+ answer — including everyone who picked commit/push gates through the old
426
+ `/verity-setup`. The first upgraded `verity init` fell back to the shipped
427
+ default and reconciled those gates away, turning Stop back on. What you chose is
428
+ still legible in `.claude/settings.json`, so init reads it.
429
+ - `verity doctor` names the artifact that is actually missing instead of telling
430
+ you to run a phase that will decline: with a Standard adopted and no analysis
431
+ config, `/verity-setup` would have answered "already configured".
432
+ - The setup skill learned the same case — Standard present, analysis config
433
+ missing — and writes only the config rather than re-synthesizing the Standard.
434
+
435
+
256
436
  ## [0.31.3] — 2026-09-03
257
437
 
258
438
  **After a rebase, Verity reviewed the wrong code.** When a branch was rebased