@codacy/verity-cli 0.31.0 → 0.31.1-experimental.02b82ff

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 +166 -0
  2. package/bin/verity.js +33 -11
  3. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,172 @@
3
3
  All notable changes to Verity are documented here. This project follows
4
4
  [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [0.31.1] — 2026-08-27
7
+
8
+ **Verity stops repeating itself.** A finding it had already closed could keep
9
+ appearing on every run, for the life of the project, with no way to end it — and
10
+ the one command you'd run to understand why would crash halfway through. Both
11
+ are fixed.
12
+
13
+ ```bash
14
+ npm install -g @codacy/verity-cli
15
+ ```
16
+
17
+ ### 🔁 A finding Verity has answered stops coming back
18
+
19
+ - **When a finding is settled — you rebutted it, you waived it, it was
20
+ dispositioned — Verity now knows.** It used to keep its own local copy of what
21
+ it had said and never update it, so a finding that was formally closed on the
22
+ service still reappeared on every run. One reported case repeated six times
23
+ across two branches, including runs that never even looked at the file.
24
+ - **`verity waive` stopped looking broken.** A waive worked, but this same stale
25
+ copy meant the finding kept printing anyway — so the disposition looked like it
26
+ had been ignored.
27
+ - **Saying it again re-opens it.** If Verity raises a settled finding a second
28
+ time, it counts as open again. Answering a finding is not a mute switch, and
29
+ a real recurrence always wins.
30
+
31
+ ### 💬 The carried-findings notice tells the truth, and offers a way out
32
+
33
+ - It **no longer calls those findings "blocking."** They are the ones that did
34
+ *not* gate your run — a passing run was printing "1 blocking finding(s)" every
35
+ turn, an alarm the gate itself had already decided not to act on.
36
+ - It now **names the way to resolve them**, instead of repeating a problem with
37
+ no stated exit.
38
+
39
+ ### 🐛 Fixes
40
+
41
+ - **`verity status` no longer crashes partway through.** A pending item with no
42
+ priority threw an error mid-report, so everything below it — your active
43
+ tasks, your run history — silently never printed. It was also the one screen
44
+ that would have explained the repeating finding above.
45
+
46
+ ## [0.31.0] — 2026-08-25
47
+
48
+ **The gate reviews exactly the change you're shipping — and people get the last
49
+ word.** The theme of 0.31 is evidence and disposition. Every claim the gate
50
+ makes is now bound to bytes it actually reviewed: a finding about a file that
51
+ isn't in your change can no longer block it, leftovers from a previous run can
52
+ no longer resurface as fresh criticals, and an old plan file that happens to be
53
+ committed can no longer hijack what a push is judged against. Commits and
54
+ pushes become a first-class review moment — the whole change ships for review,
55
+ to a stronger model, on its own budget. And two new verbs, `verity waive` and
56
+ `verity ignore`, let humans and agents put a disposition on the record that the
57
+ gate *verifies* rather than obeys: every one is reasoned, audited, and voids
58
+ itself the moment the evidence changes.
59
+
60
+ ```bash
61
+ npm install -g @codacy/verity-cli
62
+ verity init # optional — refreshes the installed skill docs
63
+ ```
64
+
65
+ ### 🧾 No finding without the bytes
66
+
67
+ - **A finding about a file that wasn't in the change can no longer block.**
68
+ Findings citing files whose bytes were not under review are downgraded to
69
+ pre-existing — downgraded, never dropped, and counted in the run's metadata.
70
+ This closes a real class of false blocks reproduced from production: stale
71
+ pending items from a previous run re-raised as blocking criticals against a
72
+ clean push — one of them literally labelled *"Not blocking"*.
73
+ - **It reaches every installed CLI on deploy day** — the rule is enforced
74
+ server-side, with a client-side belt on top: the guard refuses to block on a
75
+ finding citing a file it never sent.
76
+ - **What the gate said before is context, never a fresh finding.** Pending
77
+ items inform the review; they are no longer restatable as new findings.
78
+
79
+ ### 🚢 A commit or push is a first-class review moment
80
+
81
+ - **The whole change ships for review.** Budgets at `pre-commit`/`pre-push`
82
+ are raised to **120 files / ~570 KB** (the interactive Stop turn is
83
+ unchanged at 40). A 45-file commit used to arrive as 40 files with 5
84
+ silently dropped — the gate was reviewing a different change than the one
85
+ landing.
86
+ - **A stronger reviewer, when it matters most.** Git moments run on
87
+ **gpt-5.6-sol** at medium reasoning with a 3-minute budget; interactive
88
+ turns stay on the fast model. Overridable per project
89
+ (`process_constraints.git_moment_model` / `git_moment_reasoning_effort`).
90
+ Measured live: a 45-file, 318 KB push reviewed in ~52s.
91
+ - **Intent is what the change contains.** Only documents that are *part of the
92
+ push* ride along as plans. A six-month-old committed plan can no longer gate
93
+ an unrelated push — and "the plan isn't fully implemented" is never a
94
+ finding; it informs intent alignment only.
95
+ - The coverage line now carries the elapsed time — a longer review is fine
96
+ when it says so.
97
+
98
+ ### ✋ `verity waive` — accepted risk, on the record
99
+
100
+ - **A human disposition now actually unblocks the gate.** A finding your
101
+ reviewers had explicitly accepted used to re-block every commit and push,
102
+ forever, with no documented way out.
103
+ - `verity waive <pattern-id> --file <path> --reason "…"` — the reason is
104
+ mandatory (name the review, ADR, or ticket it records). The waive is bound
105
+ to the file's exact bytes: the same bytes pass for everyone, in any session
106
+ — **edit the file and the waive voids itself.** An assertion, not a mute
107
+ switch.
108
+ - Every waive lands in the statements ledger, visible in run reports; at most
109
+ 3 statements per call.
110
+ - **A waive ends a security-pushback round.** The gate resists an *agent*
111
+ arguing a security finding away; a human-attributable disposition is exactly
112
+ the adjudication that round exists to wait for.
113
+
114
+ ### 🤫 `verity ignore` and `.verityignore`
115
+
116
+ - **Declare a housekeeping window** — `verity ignore --turn --reason "…"` (or
117
+ `--for 30m`) for the agent-run `git pull` or dependency surgery that
118
+ shouldn't cost a review turn. **The declaration is checked, never
119
+ believed**: if a single file is authored during it, the whole window voids,
120
+ the review runs anyway, and the broken declaration is reported. Budgeted at
121
+ 3 per session, spent on declaration — a void never refunds the attempt.
122
+ - **`.verityignore`** — a committed, team-shared exclusion file at the repo
123
+ root, gitignore syntax: "is this file worth reviewing, ever?" Every
124
+ exclusion is named in the run's coverage ledger, never silent.
125
+ - **You can't blind the gate in the same move.** If `.verityignore` is part of
126
+ a turn's change, *no* ignore rules apply to that turn at all — writing
127
+ `src/**` into it and the vulnerability into `src/` in one turn doesn't work.
128
+ Patterns that would exclude the whole repository are refused, and a pattern
129
+ that would have hidden a really-detected secret is warned about.
130
+
131
+ ### Migrating
132
+
133
+ 1. Server-side changes — the byte witness, the git-moment profile, waive
134
+ honouring — reach **every** installed client on deploy day with no action.
135
+ 2. `npm install -g @codacy/verity-cli` for the new commands (`verity waive`,
136
+ `verity ignore`, `verity config service-url`) and the raised git-moment
137
+ budget on the client side.
138
+ 3. Optionally re-run `verity init` once per repo to refresh the installed
139
+ skill docs; the CLAUDE.md guidance block updates automatically.
140
+ 4. To use `.verityignore`: create it at the repo root (gitignore syntax) and
141
+ commit it.
142
+
143
+ [0.31.0]: https://github.com/codacy/verity-core/releases/tag/v0.31.0
144
+
145
+ ## [0.30.1] — 2026-08-24
146
+
147
+ **The guard reviews the tree your command targets.** A focused release for
148
+ everyone working with git worktrees — and the first piece of making routine
149
+ turns free.
150
+
151
+ - **Worktrees are reviewed correctly.** `cd ../wt && git push` used to review
152
+ the *main checkout's* push range; pushing from a worktree that had diverged
153
+ from its upstream reviewed drift that wasn't even on disk. The guard now
154
+ resolves *which repo, which tree, which range* from the command itself (cd
155
+ chains, `git -C`, remotes and refspecs), with ranges anchored at the
156
+ merge-base — worktrees can live anywhere.
157
+ - **Named refusals over guesses.** When the command's target can't be resolved
158
+ (e.g. `--git-dir`, `GIT_WORK_TREE=`, or two pushes at two targets in one
159
+ command), the guard allows *without* review and says so loudly — it never
160
+ issues a verdict about a tree it guessed.
161
+ - **Coverage is printed on every run**: the moment, tree, branch, range, the
162
+ files reviewed, and what was excluded and why.
163
+ - **A user-typed `! command` turn no longer costs a Verity turn.** `! git
164
+ pull` used to run the full pipeline and then narrate, in Verity's voice, a
165
+ turn nobody took. It now exits fast and silent — keyed on evidence, never
166
+ the prompt: any authored file or agent tool call defeats the skip, and
167
+ commands that can write code (`! npm install`, redirects, pipes) are still
168
+ reviewed.
169
+
170
+ [0.30.1]: https://github.com/codacy/verity-core/releases/tag/v0.30.1
171
+
6
172
  ## [0.30.0] — 2026-08-13
7
173
 
8
174
  **Verity feels smarter, and tuned to the session you're in.** The theme of 0.30
package/bin/verity.js CHANGED
@@ -10506,7 +10506,7 @@ var SECURITY_PATTERNS = [
10506
10506
  /Dockerfile/
10507
10507
  ];
10508
10508
  var PROD_SERVICE_URL = "https://ofcamwrjwrkazqvdchko.supabase.co/functions/v1";
10509
- var DEFAULT_SERVICE_URL = "".length > 0 ? "" : PROD_SERVICE_URL;
10509
+ var DEFAULT_SERVICE_URL = "https://wukeddyzpijoegyajtnc.supabase.co/functions/v1".length > 0 ? "https://wukeddyzpijoegyajtnc.supabase.co/functions/v1" : PROD_SERVICE_URL;
10510
10510
  var GITHUB_CLIENT_ID = "Iv23li88HxAi3ZrbYzWh";
10511
10511
  var GITHUB_DEVICE_CODE_URL = "https://github.com/login/device/code";
10512
10512
  var GITHUB_ACCESS_TOKEN_URL = "https://github.com/login/oauth/access_token";
@@ -14136,6 +14136,11 @@ var REANCHOR_WINDOW = 20;
14136
14136
  var STATEMENT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
14137
14137
  var DEFAULT_MEMORY_BUDGET_BYTES = 4096;
14138
14138
 
14139
+ // src/lib/dossier/events.ts
14140
+ function statementAnchorKey(file, patternId) {
14141
+ return `${file}::${patternId}`;
14142
+ }
14143
+
14139
14144
  // src/lib/dossier/log.ts
14140
14145
  var import_node_crypto4 = require("node:crypto");
14141
14146
  var import_node_fs10 = require("node:fs");
@@ -14419,6 +14424,7 @@ function reduce(state, events, now) {
14419
14424
  existing.line_sha = ev.line_sha ?? existing.line_sha;
14420
14425
  existing.register = ev.register;
14421
14426
  if (existing.outcome === "fixed") existing.outcome = "recurred";
14427
+ else if (existing.outcome !== "open") existing.outcome = "open";
14422
14428
  break;
14423
14429
  }
14424
14430
  byAnchor.set(ev.anchor_key, {
@@ -15349,10 +15355,10 @@ function recordVerdict(d, v) {
15349
15355
  const at = src?.[f.line - 1];
15350
15356
  appendEvent(d, {
15351
15357
  k: "statement",
15352
- // Stable across title and line drift 374 of 378 recurring sites (98.9%)
15353
- // carry title drift, so a title-inclusive key fragments the recurrence it
15354
- // exists to detect.
15355
- anchor_key: `${f.file}::${f.pattern_id}`,
15358
+ // ONE OWNER. The server's settled feed is resolved against this exact
15359
+ // key in `13-reconcile.ts`; spelling the template literal twice is how the
15360
+ // two sides drift apart. See `statementAnchorKey`.
15361
+ anchor_key: statementAnchorKey(f.file, f.pattern_id),
15356
15362
  file: f.file,
15357
15363
  line: f.line,
15358
15364
  pattern_id: f.pattern_id,
@@ -17229,7 +17235,8 @@ function registerStatusCommand(program2) {
17229
17235
  printInfo("");
17230
17236
  printInfo("--- Pending Items ---");
17231
17237
  for (const item of mem.pending_items) {
17232
- printInfo(` [${item.priority.toUpperCase()}] ${item.description}`);
17238
+ const priority = typeof item.priority === "string" && item.priority.length > 0 ? item.priority.toUpperCase() : "UNSPECIFIED";
17239
+ printInfo(` [${priority}] ${item.description ?? "(no description)"}`);
17233
17240
  }
17234
17241
  }
17235
17242
  const recentTasks = mem.recent_tasks;
@@ -18452,7 +18459,7 @@ function channelSilence(input) {
18452
18459
  // src/lib/cli-version.ts
18453
18460
  function cliVersion() {
18454
18461
  try {
18455
- return true ? "0.31.0" : "dev";
18462
+ return true ? "0.31.1-experimental.02b82ff" : "dev";
18456
18463
  } catch {
18457
18464
  return "dev";
18458
18465
  }
@@ -18702,9 +18709,10 @@ function describeOpenElsewhere(open) {
18702
18709
  const lines = open.slice(0, 5).map((o) => ` ${o.file}:${o.line} [${o.pattern_id}]`);
18703
18710
  const more = open.length > 5 ? `
18704
18711
  (+${open.length - 5} more)` : "";
18705
- return `STILL OPEN ELSEWHERE. ${open.length} blocking finding(s) Verity raised earlier are still present in files this run did not review:
18712
+ return `STILL OPEN ELSEWHERE. ${open.length} finding(s) Verity raised earlier are still on disk in files this run did not review:
18706
18713
  ${lines.join("\n")}${more}
18707
- This verdict covers the current change only. The tree is not clean.`;
18714
+ They did not gate this run \u2014 this verdict covers the current change only. The tree is not clean.
18715
+ Fix them, or record a disposition: verity waive <pattern-id> --file <path> --reason "\u2026"`;
18708
18716
  }
18709
18717
 
18710
18718
  // src/commands/analyze/exit.ts
@@ -21042,6 +21050,20 @@ async function reconcile(run) {
21042
21050
  })() : [];
21043
21051
  if (memorySession) {
21044
21052
  try {
21053
+ const settledSites = response.metadata?.settled_sites;
21054
+ if (Array.isArray(settledSites)) {
21055
+ for (const site of settledSites) {
21056
+ const s = site;
21057
+ const file = typeof s?.file === "string" ? s.file : null;
21058
+ const patternId = typeof s?.pattern_id === "string" ? s.pattern_id : null;
21059
+ if (!file || !patternId) continue;
21060
+ appendEvent(memorySession.d, {
21061
+ k: "outcome",
21062
+ anchor_key: statementAnchorKey(file, patternId),
21063
+ outcome: "answered"
21064
+ });
21065
+ }
21066
+ }
21045
21067
  recordVerdict(memorySession.d, {
21046
21068
  runId: response.run_id ?? turnId,
21047
21069
  decision,
@@ -23580,8 +23602,8 @@ function registerTelemetryCommands(program2) {
23580
23602
  }
23581
23603
 
23582
23604
  // src/cli.ts
23583
- program.name("verity").description("CLI for Verity quality gate service").version("0.31.0").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
23584
- installStderrLog(actionCommand.name(), process.argv.slice(2), "0.31.0");
23605
+ program.name("verity").description("CLI for Verity quality gate service").version("0.31.1-experimental.02b82ff").option("--token <token>", "Override authentication token").option("--service-url <url>", "Override service URL").option("--verbose", "Log HTTP requests/responses to stderr").hook("preAction", async (_thisCommand, actionCommand) => {
23606
+ installStderrLog(actionCommand.name(), process.argv.slice(2), "0.31.1-experimental.02b82ff");
23585
23607
  setUserNamedServiceUrl(program.opts().serviceUrl);
23586
23608
  try {
23587
23609
  await foldLegacyLocalCredential();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codacy/verity-cli",
3
- "version": "0.31.0",
3
+ "version": "0.31.1-experimental.02b82ff",
4
4
  "description": "CLI for Verity quality gate service",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "homepage": "https://verity.md",