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

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