fallow 3.41.0 → 3.42.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/capabilities.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "3.41.0",
3
+ "version": "3.42.0",
4
4
  "manifest_version": "1",
5
5
  "description": "Codebase analyzer for TypeScript/JavaScript: unused code, circular dependencies, code duplication, complexity hotspots, and architecture boundary violations",
6
6
  "global_flags": [
@@ -1261,6 +1261,22 @@
1261
1261
  "required": false,
1262
1262
  "description": "Run at most N covered mutants, in rank order. Uncovered mutants do not count. The others are `pending`"
1263
1263
  },
1264
+ {
1265
+ "name": "--mutants-per-line",
1266
+ "type": "string",
1267
+ "required": false,
1268
+ "description": "Keep at most N mutants on each source line. The plan keeps the most productive mutants of the line (relational, condition, arithmetic and logical operators first). The others are `pending` with the reason `sampled-out` and do not run (default: the `mutation.mutantsPerLine` key, else each mutant)"
1269
+ },
1270
+ {
1271
+ "name": "--function-scope",
1272
+ "type": "bool",
1273
+ "required": false,
1274
+ "description": "Widen each changed line to the whole function that holds it, so that a changed parameter or signature selects the mutants of the function. Only the changed-code scope uses it (default: the `mutation.functionScope` key, else the changed lines only)",
1275
+ "possible_values": [
1276
+ "true",
1277
+ "false"
1278
+ ]
1279
+ },
1264
1280
  {
1265
1281
  "name": "--time-budget",
1266
1282
  "type": "string",
@@ -1309,7 +1325,7 @@
1309
1325
  "name": "--operators",
1310
1326
  "type": "string",
1311
1327
  "required": false,
1312
- "description": "The operators to use, comma-separated (default: each operator)"
1328
+ "description": "The operators to use, comma-separated. Default: the default set. The opt-in operators (block-statement, array-literal, object-literal, method-expression, switch-case, call-expression, throw-statement, regex-constructor, regex-assertion) run only when named here"
1313
1329
  },
1314
1330
  {
1315
1331
  "name": "--verdicts",
@@ -1333,7 +1349,7 @@
1333
1349
  "name": "--typecheck",
1334
1350
  "type": "bool",
1335
1351
  "required": false,
1336
- "description": "Type-check each survived mutant through the `--type-aware` companion. A survivor that does not type-check becomes `compile_error` and leaves the score",
1352
+ "description": "Type-check each survived mutant through the `--type-aware` companion. A survivor that does not type-check becomes `compile_error` and leaves the score. An optional-chaining survivor on a receiver whose type excludes `null` and `undefined` gets an advisory `equivalence_hint`. Its status and the score do not change",
1337
1353
  "possible_values": [
1338
1354
  "true",
1339
1355
  "false"
@@ -2692,6 +2708,24 @@
2692
2708
  "type": "string",
2693
2709
  "required": true,
2694
2710
  "description": "Path to a fallow JSON results file produced by `--format json` (dead-code, architecture, dupes, health, audit, security, or bare combined)"
2711
+ },
2712
+ {
2713
+ "name": "--mutation-report",
2714
+ "type": "string",
2715
+ "required": false,
2716
+ "description": "A saved `fallow mutation --format json` report, or the JSON error envelope of a failed run, to render with the results. Applies to the pr-comment, review, github-summary, github-annotations and codeclimate formats only. The paths in the report are relative to the root of the mutation run, which must be the `--root` of this call"
2717
+ },
2718
+ {
2719
+ "name": "--mutation-not-run",
2720
+ "type": "string",
2721
+ "required": false,
2722
+ "description": "Why mutation testing did not run in this job, so the render states it. Applies to the same formats as `--mutation-report`",
2723
+ "possible_values": [
2724
+ "event-refused",
2725
+ "fork-refused",
2726
+ "no-change-scope",
2727
+ "interrupted"
2728
+ ]
2695
2729
  }
2696
2730
  ]
2697
2731
  },
@@ -7249,6 +7283,36 @@
7249
7283
  "license": "free",
7250
7284
  "license_note": null,
7251
7285
  "docs_url": "https://fallow.tools/docs/cli/audit/#diff-risk-rules"
7286
+ },
7287
+ {
7288
+ "id": "mutation-survived",
7289
+ "rule_id": "fallow/mutation-survived",
7290
+ "command": "mutation",
7291
+ "category": "Tests",
7292
+ "description": "A small code change made no test fail",
7293
+ "label": null,
7294
+ "config_key": null,
7295
+ "registry_index": null,
7296
+ "aliases": [],
7297
+ "lsp": false,
7298
+ "filter_flag": null,
7299
+ "result_key": null,
7300
+ "summary_label": null,
7301
+ "summary_docs_anchor": null,
7302
+ "sarif_rule_ids": null,
7303
+ "codeclimate_check_names": null,
7304
+ "ts_alias": null,
7305
+ "counts_in_total": false,
7306
+ "fixable": false,
7307
+ "suppressible": false,
7308
+ "suppress_comment": null,
7309
+ "default_severity": null,
7310
+ "opt_in": null,
7311
+ "frameworks": [],
7312
+ "note": null,
7313
+ "license": "free",
7314
+ "license_note": null,
7315
+ "docs_url": "https://fallow.tools/docs/cli/mutation/"
7252
7316
  }
7253
7317
  ],
7254
7318
  "suppression_comments": {
@@ -7946,6 +8010,8 @@
7946
8010
  "all",
7947
8011
  "paths",
7948
8012
  "max_mutants",
8013
+ "mutants_per_line",
8014
+ "function_scope",
7949
8015
  "operators"
7950
8016
  ],
7951
8017
  "license": "free",
@@ -8576,7 +8642,7 @@
8576
8642
  ]
8577
8643
  },
8578
8644
  "plugins": {
8579
- "count": 150,
8645
+ "count": 156,
8580
8646
  "note": "Built-in framework plugins, auto-activated when their enabler dependency is present; run fallow list --plugins for the set active in a specific project",
8581
8647
  "names": [
8582
8648
  "nextjs",
@@ -8592,6 +8658,7 @@
8592
8658
  "redwoodsdk",
8593
8659
  "tanstack-router",
8594
8660
  "waku",
8661
+ "solid-start",
8595
8662
  "react-native",
8596
8663
  "expo",
8597
8664
  "expo-router",
@@ -8612,6 +8679,7 @@
8612
8679
  "supabase",
8613
8680
  "vitepress",
8614
8681
  "rspress",
8682
+ "dumi",
8615
8683
  "next-intl",
8616
8684
  "relay",
8617
8685
  "electron",
@@ -8630,6 +8698,7 @@
8630
8698
  "ember",
8631
8699
  "eve",
8632
8700
  "vite",
8701
+ "vite-plugin-pages",
8633
8702
  "vscode",
8634
8703
  "webpack",
8635
8704
  "rollup",
@@ -8673,6 +8742,7 @@
8673
8742
  "tailwind",
8674
8743
  "postcss",
8675
8744
  "unocss",
8745
+ "unplugin-icons",
8676
8746
  "pandacss",
8677
8747
  "prisma",
8678
8748
  "drizzle",
@@ -8710,10 +8780,12 @@
8710
8780
  "typedoc",
8711
8781
  "openapi-ts",
8712
8782
  "plop",
8783
+ "gulp",
8713
8784
  "c8",
8714
8785
  "nyc",
8715
8786
  "msw",
8716
8787
  "napi-rs",
8788
+ "n8n",
8717
8789
  "opencode",
8718
8790
  "nodemon",
8719
8791
  "pm2",
@@ -3336,6 +3336,36 @@
3336
3336
  "license_note": null,
3337
3337
  "docs_url": "https://fallow.tools/docs/cli/security/"
3338
3338
  },
3339
+ {
3340
+ "id": "mutation-survived",
3341
+ "rule_id": "fallow/mutation-survived",
3342
+ "command": "mutation",
3343
+ "category": "Tests",
3344
+ "description": "A small code change made no test fail",
3345
+ "label": null,
3346
+ "config_key": null,
3347
+ "registry_index": null,
3348
+ "aliases": [],
3349
+ "lsp": false,
3350
+ "filter_flag": null,
3351
+ "result_key": null,
3352
+ "summary_label": null,
3353
+ "summary_docs_anchor": null,
3354
+ "sarif_rule_ids": null,
3355
+ "codeclimate_check_names": null,
3356
+ "ts_alias": null,
3357
+ "counts_in_total": false,
3358
+ "fixable": false,
3359
+ "suppressible": false,
3360
+ "suppress_comment": null,
3361
+ "default_severity": null,
3362
+ "opt_in": null,
3363
+ "frameworks": [],
3364
+ "note": null,
3365
+ "license": "free",
3366
+ "license_note": null,
3367
+ "docs_url": "https://fallow.tools/docs/cli/mutation/"
3368
+ },
3339
3369
  {
3340
3370
  "id": "mysql-multiple-statements",
3341
3371
  "rule_id": "security/mysql-multiple-statements",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "3.41.0",
3
+ "version": "3.42.0",
4
4
  "mcpName": "io.github.fallow-rs/fallow",
5
5
  "description": "Codebase intelligence for TypeScript and JavaScript: health, complexity, duplication, architecture, styling drift, and unused code from one graph. CLI, LSP, and MCP server. Zero config for over 100 frameworks.",
6
6
  "license": "MIT",
@@ -92,14 +92,14 @@
92
92
  "@tanstack/intent": "0.5.6"
93
93
  },
94
94
  "optionalDependencies": {
95
- "@fallow-cli/darwin-arm64": "3.41.0",
96
- "@fallow-cli/darwin-x64": "3.41.0",
97
- "@fallow-cli/linux-x64-gnu": "3.41.0",
98
- "@fallow-cli/linux-arm64-gnu": "3.41.0",
99
- "@fallow-cli/linux-x64-musl": "3.41.0",
100
- "@fallow-cli/linux-arm64-musl": "3.41.0",
101
- "@fallow-cli/win32-arm64-msvc": "3.41.0",
102
- "@fallow-cli/win32-x64-msvc": "3.41.0",
103
- "fallow-type-aware": "3.41.0"
95
+ "@fallow-cli/darwin-arm64": "3.42.0",
96
+ "@fallow-cli/darwin-x64": "3.42.0",
97
+ "@fallow-cli/linux-x64-gnu": "3.42.0",
98
+ "@fallow-cli/linux-arm64-gnu": "3.42.0",
99
+ "@fallow-cli/linux-x64-musl": "3.42.0",
100
+ "@fallow-cli/linux-arm64-musl": "3.42.0",
101
+ "@fallow-cli/win32-arm64-msvc": "3.42.0",
102
+ "@fallow-cli/win32-x64-msvc": "3.42.0",
103
+ "fallow-type-aware": "3.42.0"
104
104
  }
105
105
  }
package/schema.json CHANGED
@@ -189,7 +189,7 @@
189
189
  }
190
190
  },
191
191
  "mutation": {
192
- "description": "Configures the explicit `fallow mutation` workflow: `runner` (`auto`\nor `vitest`), `operators` (kebab-case names, default each operator),\n`minScore` (0 to 100; a lower score exits with code 1), and\n`concurrency` (half the logical cores). No key starts a run, and the\nside-effect override is a CLI flag only.",
192
+ "description": "Configures the explicit `fallow mutation` workflow: `runner` (`auto`\nor `vitest`), `operators` (kebab-case names, default the default set),\n`minScore` (0 to 100; a lower score exits with code 1), and\n`concurrency` (half the logical cores). No key starts a run, and the\nside-effect override is a CLI flag only.",
193
193
  "$ref": "#/$defs/MutationConfig"
194
194
  },
195
195
  "health": {
@@ -1174,7 +1174,7 @@
1174
1174
  "default": "auto"
1175
1175
  },
1176
1176
  "operators": {
1177
- "description": "The operators to use. Unset uses each operator. `--operators` wins.",
1177
+ "description": "The operators to use. Unset uses the default set. An opt-in operator\nruns only when this list or `--operators` names it. `--operators`\nwins.",
1178
1178
  "type": [
1179
1179
  "array",
1180
1180
  "null"
@@ -1202,8 +1202,24 @@
1202
1202
  "format": "uint",
1203
1203
  "minimum": 1
1204
1204
  },
1205
+ "mutantsPerLine": {
1206
+ "description": "The maximum number of mutants on one source line. The plan keeps the\nmost productive mutants of the line (relational, condition,\narithmetic and logical operators first). The others are `pending`\nwith the reason `sampled-out`. Unset keeps each mutant.\n`--mutants-per-line` wins.",
1207
+ "type": [
1208
+ "integer",
1209
+ "null"
1210
+ ],
1211
+ "format": "uint",
1212
+ "minimum": 1
1213
+ },
1214
+ "functionScope": {
1215
+ "description": "Widen each changed line to the whole function that holds it, so that a\nchange to a parameter or a signature selects the mutants of the\nfunction. Only the changed-code scope uses it. Unset or `false` mutates\nthe changed lines only. `--function-scope` turns it on.",
1216
+ "type": [
1217
+ "boolean",
1218
+ "null"
1219
+ ]
1220
+ },
1205
1221
  "typecheck": {
1206
- "description": "Type-check each survived mutant through the TypeScript-Go companion\nof `--type-aware`. A survivor that does not type-check becomes\n`compile_error` and does not count in the score. Unset or `false`\nchecks no survivor. `--typecheck` turns the check on.",
1222
+ "description": "Type-check each survived mutant through the TypeScript-Go companion\nof `--type-aware`. A survivor that does not type-check becomes\n`compile_error` and does not count in the score. A survivor that\nremoves an optional-chaining link from a receiver whose type excludes\n`null` and `undefined` gets an advisory `equivalence_hint`. Its status\nand the score do not change. Unset or `false` checks no survivor.\n`--typecheck` turns the check on.",
1207
1223
  "type": [
1208
1224
  "boolean",
1209
1225
  "null"
@@ -1293,7 +1309,7 @@
1293
1309
  "const": "boolean-literal"
1294
1310
  },
1295
1311
  {
1296
- "description": "A string literal emptied or filled.",
1312
+ "description": "A string or template literal emptied or filled.",
1297
1313
  "type": "string",
1298
1314
  "const": "string-literal"
1299
1315
  },
@@ -1303,7 +1319,7 @@
1303
1319
  "const": "optional-chaining"
1304
1320
  },
1305
1321
  {
1306
- "description": "One token of a regular expression literal changed: an anchor\nremoved, a character class negated, or a class escape with the\nopposite case.",
1322
+ "description": "One token of a regular expression literal changed: an anchor or a\nquantifier removed, a `{n,m}` range shortened to `{n}`, a character\nclass negated, or a class escape with the opposite case.",
1307
1323
  "type": "string",
1308
1324
  "const": "regex-literal"
1309
1325
  },
@@ -1311,6 +1327,51 @@
1311
1327
  "description": "`z.number().int()` to `z.number()` in a module-level `const`\ninitializer: one call link of a fluent chain removed.",
1312
1328
  "type": "string",
1313
1329
  "const": "removed-chain-link"
1330
+ },
1331
+ {
1332
+ "description": "Opt-in. The statements of a block or function body removed.",
1333
+ "type": "string",
1334
+ "const": "block-statement"
1335
+ },
1336
+ {
1337
+ "description": "Opt-in. `[x]` to `[]`, and `[]` to `[\"fallow\"]`.",
1338
+ "type": "string",
1339
+ "const": "array-literal"
1340
+ },
1341
+ {
1342
+ "description": "Opt-in. A non-empty object literal to `{}`.",
1343
+ "type": "string",
1344
+ "const": "object-literal"
1345
+ },
1346
+ {
1347
+ "description": "Opt-in. `startsWith` to `endsWith` and the other method pairs, or\n`s.trim()` to `s`.",
1348
+ "type": "string",
1349
+ "const": "method-expression"
1350
+ },
1351
+ {
1352
+ "description": "Opt-in. The statements of a `case` clause removed.",
1353
+ "type": "string",
1354
+ "const": "switch-case"
1355
+ },
1356
+ {
1357
+ "description": "Opt-in. A call in an expression position to `void 0`.",
1358
+ "type": "string",
1359
+ "const": "call-expression"
1360
+ },
1361
+ {
1362
+ "description": "Opt-in. A `throw new X(...)` statement removed.",
1363
+ "type": "string",
1364
+ "const": "throw-statement"
1365
+ },
1366
+ {
1367
+ "description": "Opt-in. The regex changes applied to a `new RegExp(\"...\")` pattern.",
1368
+ "type": "string",
1369
+ "const": "regex-constructor"
1370
+ },
1371
+ {
1372
+ "description": "Opt-in. A lookaround negated, or `\\b` and `\\B` swapped.",
1373
+ "type": "string",
1374
+ "const": "regex-assertion"
1314
1375
  }
1315
1376
  ]
1316
1377
  },
@@ -53,7 +53,7 @@ Every fallow command with its purpose and key flags. The table is regenerated fr
53
53
  | `type-aware` | Inspect the optional TypeScript semantic companion | |
54
54
  | `doctor` | Diagnose project readiness without analysis or mutation | |
55
55
  | `similar-code` | Find semantically similar functions with a pinned local model (opt-in) | `--threshold`, `--min-lines`, `--top`, `--file` |
56
- | `mutation` | Measure how well the tests detect changes in the code (opt-in) | `--all`, `--plan`, `--max-mutants`, `--time-budget`, `--concurrency`, `--runtime`, `--runner-config`, `--allow-dirty`, `--allow-side-effects` |
56
+ | `mutation` | Measure how well the tests detect changes in the code (opt-in) | `--all`, `--plan`, `--max-mutants`, `--mutants-per-line`, `--function-scope`, `--time-budget`, `--concurrency`, `--runtime`, `--runner-config`, `--allow-dirty`, `--allow-side-effects` |
57
57
  | `inspect` | Compose one evidence bundle for a file or exported symbol, with optional Fallow Cloud production data | `--file <path>`, `--symbol <file>:<export>`, `--cloud`, `--repo <owner/repo>` |
58
58
  | `cloud` | Log in to Fallow Cloud with the device flow and store a read-only API key (login, logout) | `login --machine-name <name>`, `login --api-url <url>`, `logout` |
59
59
  | `trace` | Trace a symbol's call chain, or with `--path` the shortest import path between two modules (best-effort, syntactic; OFF the ranked path) | `symbol`, `--path <FROM> <TO>`, `--eager-only`, `--callers`, `--callees`, `--depth` |
@@ -85,7 +85,7 @@ Every fallow command with its purpose and key flags. The table is regenerated fr
85
85
  | `decision-surface` | Surface the consequential structural DECISIONS a change embeds (the apex of the review brief), each framed as a judgment question with the routed expert to ask | `--max-decisions` |
86
86
  | `impact` | Show what fallow has done for you: how many issues it is surfacing, the trend since the last recorded run, and how many commits it contained at the pre-commit gate | `--all`, `--sort`, `--limit` |
87
87
  | `security` | Surface opt-in local security candidates for agent verification (not confirmed vulnerabilities). Rule families include the graph rule `client-server-leak`, a data-driven `tainted-sink` catalogue, and the include-required `hardcoded-secret` category for provider-prefix credentials and high-entropy literals assigned to secret-shaped identifiers. Most catalogue rows require non-literal input; narrowly literal-aware rows flag deterministic unsafe literals. Rules default off; suppress a file with `// fallow-ignore-file security-sink`; scope categories with `security.categories`. Add project-local request object names with `security.requestReceivers`; it extends the built-in `req` / `request` / `ctx` / `context` / `event` allowlist for HTTP `query`, `params`, and `body` reads. `hardcoded-secret` runs only when listed in `security.categories.include`. | `--format human\|json\|sarif`, `--changed-since`, `--file`, `--diff-file`, `--workspace`, `--changed-workspaces`, `--surface`, `--ci`, `--fail-on-issues`, `--sarif-file`, `--summary` |
88
- | `report` | Render a saved `--format json` results file in another format without re-running analysis (analyze once, render annotations and the job summary from the same file). | `--from` |
88
+ | `report` | Render a saved `--format json` results file in another format without re-running analysis (analyze once, render annotations and the job summary from the same file). With a CI format, `--mutation-report` adds a saved `fallow mutation --format json` report, and `--mutation-not-run` states why mutation testing did not run. | `--from`, `--mutation-report`, `--mutation-not-run` |
89
89
  | `schema` | Dump CLI definition as JSON | |
90
90
  | `ci-template` | Print or vendor CI integration templates | |
91
91
  | `migrate` | Convert knip/jscpd config | `--dry-run`, `--from PATH` |
@@ -530,7 +530,7 @@ Human output groups paths under "Shared with your team (commit these)" and "Loca
530
530
  {
531
531
  "kind": "agent-install",
532
532
  "schema_version": 1,
533
- "fallow_version": "3.41.0",
533
+ "fallow_version": "3.42.0",
534
534
  "root": "/abs/path",
535
535
  "mode": "install",
536
536
  "dry_run": false,
@@ -742,7 +742,7 @@ fallow health --format json --quiet --trend
742
742
  {
743
743
  "kind": "health",
744
744
  "schema_version": 7,
745
- "version": "3.41.0",
745
+ "version": "3.42.0",
746
746
  "elapsed_ms": 32,
747
747
  "summary": {
748
748
  "files_analyzed": 482,
@@ -1217,7 +1217,7 @@ fallow audit \
1217
1217
  {
1218
1218
  "kind": "audit",
1219
1219
  "schema_version": 7,
1220
- "version": "3.41.0",
1220
+ "version": "3.42.0",
1221
1221
  "command": "audit",
1222
1222
  "verdict": "fail",
1223
1223
  "changed_files_count": 12,
@@ -1305,7 +1305,7 @@ fallow flags --format json --quiet --workspace my-package
1305
1305
  ```json
1306
1306
  {
1307
1307
  "schema_version": 7,
1308
- "version": "3.41.0",
1308
+ "version": "3.42.0",
1309
1309
  "elapsed_ms": 116,
1310
1310
  "feature_flags": [],
1311
1311
  "total_flags": 0
@@ -1406,7 +1406,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1406
1406
  {
1407
1407
  "kind": "security",
1408
1408
  "schema_version": "4",
1409
- "version": "3.41.0",
1409
+ "version": "3.42.0",
1410
1410
  "elapsed_ms": 42,
1411
1411
  "config": {
1412
1412
  "rules": {
@@ -1435,7 +1435,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1435
1435
  {
1436
1436
  "kind": "security",
1437
1437
  "schema_version": "4",
1438
- "version": "3.41.0",
1438
+ "version": "3.42.0",
1439
1439
  "elapsed_ms": 42,
1440
1440
  "config": {
1441
1441
  "rules": {
@@ -2263,7 +2263,7 @@ Use this mode to check whether specific tests are redundant without a full kill
2263
2263
 
2264
2264
  - Only the mutants that a target test covers run. The other mutants are `pruned` with `prune_reason: "no-target-coverage"`.
2265
2265
  - Each mutant runs its target tests with bail disabled, then its other covering tests with bail enabled, up to the first failure.
2266
- - `kill_matrix.targets` lists each target with the `test_ids` that it selects. A target that selects no test exits `2` with `FALLOW_MUTATION_TARGET_UNMATCHED`.
2266
+ - `kill_matrix.targets` lists each target with the `test_ids` that it selects. A target that selects no test exits `2` with `FALLOW_MUTATION_TARGET_UNMATCHED`. A test ID target that names a duplicate test ID (two tests of one file with the same title) exits `2` with `FALLOW_MUTATION_TARGET_DUPLICATE_TEST_ID`. A file target drops the duplicate IDs, and the `duplicate-test-ids` entry of `errors` names them.
2267
2267
  - Each target has its own `status` (`complete` or `incomplete`) and `reasons`. Only the tests of a complete target can be candidates. `candidates` can be nonempty while the top-level `status` is `incomplete`.
2268
2268
  - `kill_matrix.tests` has rows for target tests only. `unique_kills` are kills that no other test detects, target or not. `target_only_kills` lists kills that only other targets share, each with those `targets`. `subsuming_tests` is empty (note `subsumers-not-computed`).
2269
2269
  - A target with kills and no `unique_kills` is a candidate. With `target_only_kills`, it stays redundant only while one of the sharing targets stays. Do not remove all sharing targets together.
@@ -2331,7 +2331,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
2331
2331
  {
2332
2332
  "kind": "dead-code",
2333
2333
  "schema_version": 7,
2334
- "version": "3.41.0",
2334
+ "version": "3.42.0",
2335
2335
  "elapsed_ms": 45,
2336
2336
  "total_issues": 12,
2337
2337
  "entry_points": {
@@ -2491,7 +2491,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
2491
2491
  {
2492
2492
  "kind": "dupes",
2493
2493
  "schema_version": 7,
2494
- "version": "3.41.0",
2494
+ "version": "3.42.0",
2495
2495
  "elapsed_ms": 82,
2496
2496
  "total_clones": 15,
2497
2497
  "total_lines_duplicated": 230,
@@ -2535,11 +2535,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
2535
2535
  {
2536
2536
  "kind": "combined",
2537
2537
  "schema_version": 7,
2538
- "version": "3.41.0",
2538
+ "version": "3.42.0",
2539
2539
  "elapsed_ms": 159,
2540
2540
  "check": {
2541
2541
  "schema_version": 7,
2542
- "version": "3.41.0",
2542
+ "version": "3.42.0",
2543
2543
  "elapsed_ms": 45,
2544
2544
  "total_issues": 12,
2545
2545
  "unused_files": [],
@@ -90,6 +90,7 @@ The `generated:issue-types` table below is regenerated from `fallow schema` by s
90
90
  | `test-only-branch` | - | - | `// fallow-ignore-next-line test-only-branch` | The change adds a test-environment branch to source code |
91
91
  | `diverged-clone-sibling` | - | - | `// fallow-ignore-next-line diverged-clone-sibling` | The change edits one copy of duplicated code but not its siblings |
92
92
  | `added-dependency` | - | - | - | The change adds a dependency. Config suppression only, because `package.json` cannot hold a comment: set `added-dependency` to `off` for the path in an `overrides` entry. |
93
+ | `mutation-survived` | - | - | - | A small code change made no test fail |
93
94
 
94
95
  Runtime-coverage verdicts and the full security sink catalogue are listed by `fallow schema` (`issue_types`).
95
96
  <!-- generated:issue-types:end -->
@@ -18,7 +18,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
18
18
  | `security_candidates` | analysis | free | `fallow security --format json --quiet` | `gate`, `surface`, `changed_since`, `paths` | Unverified local security candidates, not confirmed vulnerabilities (`fallow security --format json`). Read `security_findings[]` for category, CWE, severity, evidence, trace, optional `reachability`, blind-spot counters, and optional `unresolved_callee_diagnostics` samples for dynamic callee follow-up. `severity` is a review-priority tier, not a verified vulnerability verdict. Each finding also carries an agent-actionable `candidate` (`source_kind`/`sink`/`boundary`), where URL-category sinks may include `url_shape` (`fixed-origin-dynamic-path` or `dynamic-origin`), an optional `taint_flow` source-to-sink triple, and a stable `finding_id` (equal to the SARIF fingerprint) for cross-run correlation; there is no `impact` field (deciding exploitability is the agent's job). Set `surface: true` to include top-level `attack_surface[]` entries with defensive-boundary prompts for a verifier. Set `gate` to `new` for changed-line candidates or `newly-reachable` for candidates that became reachable from entry points; `newly-reachable` requires `changed_since`. `reachability.untrusted_source_trace` is module-level import context only and does not prove value flow; `reachability.taint_confidence` tiers each reachable candidate as `arg-level` (sink argument traces to a same-module source read, strong) or `module-level` (only the module is import-reachable from a source, weak), so tier from this field instead of the evidence text. Verify trace, reachability context, severity, and evidence before editing code. Supports `root`, `config`, `workspace`, `paths`, `changed_since`, `changed_workspaces`, `surface`, `gate`, `no_cache`, and `threads`; `paths` forwards repeated `fallow security --file` filters for finding anchors, trace hops, untrusted-source reachability trace hops, and unresolved-callee diagnostics. See <https://fallow.tools/docs/cli/security-agent-verification/> for the verifier packet and verdict recipe. Inherits `FALLOW_DIFF_FILE` from the server environment for line-level diff scoping; raise `FALLOW_TIMEOUT_SECS` for large repos. |
19
19
  | `find_similar_code` | analysis | free | `fallow similar-code --format json --quiet` | `threshold`, `min_lines`, `top`, `changed_since`, `paths` | Find unverified semantically similar function candidates with the exact pinned local model. Discovery is read-only and never authorizes or performs model setup. Scoped output materializes the exact admitted files once in `generation.scope.paths` as provenance. Ask the user to run `fallow similar-code setup --local` when setup is missing. Cold local inference has a dedicated 15-minute subprocess window. |
20
20
  | `inspect_similar_code` | trace | free | `fallow similar-code inspect <candidate-id> --candidates <report.json> --format json --quiet` | `candidate_id`, `snapshot` | Inspect one exact unverified candidate without rerunning provider retrieval or global ranking. Pass `candidate_id` plus a bounded typed snapshot containing the unchanged discovery `schema_version`, `generation`, selected `candidate`, `completion`, and `diagnostics`. Current source is re-extracted and both endpoint hashes must still match, so stale source fails closed. Keep candidate worthiness, behavioral equivalence, and refactor safety as separate verdicts, and abstain when evidence is incomplete. |
21
- | `mutation_plan` | analysis | free | `fallow mutation --plan --format json --quiet` | `changed_since`, `all`, `paths`, `max_mutants`, `operators` | Static mutation plan for changed code: mutant ids, operators, dispositions, and static test files; runs no tests |
21
+ | `mutation_plan` | analysis | free | `fallow mutation --plan --format json --quiet` | `changed_since`, `all`, `paths`, `max_mutants`, `mutants_per_line`, `function_scope`, `operators` | Static mutation plan for changed code: mutant ids, operators, dispositions, and static test files; runs no tests |
22
22
  | `mutation_inspect` | trace | free | `fallow mutation inspect <mutant-id> [--report <report.json>] --format json --quiet` | `mutant_id`, `report` | Inspect one mutant of a saved mutation report (default: the last run report), with a stale status when its source changed; runs no tests |
23
23
  | `mutation_tasks` | trace | free | `fallow mutation tasks [--report <report.json>] --format json --quiet` | `report` | The open tasks of a saved mutation report (default: the last run report) as one batch: each survived or uncovered mutant with its source lines before and after the change; runs no tests |
24
24
  | `inspect_target` | analysis | free | `fallow inspect --format json --quiet` | `target`, `production`, `include_churn`, `cloud` | Compose one evidence bundle for a file or exported symbol. File targets use `target: { type: "file", file }`; symbol targets use `target: { type: "symbol", file, export_name }`. Returns `kind: "inspect_target"`, normalized target identity, `trace_file`, optional `trace_export`, file-scoped dead-code actions, duplication groups filtered to the file, complexity findings filtered to the file, and security candidates scoped to the file. Set `include_churn: true` to add target-level git churn from the health hotspot subsystem. Churn is off by default, and unavailable git history or analysis failures remain explicit section states. Evidence sections carry `status` and `scope`; symbol targets warn when supporting evidence is file-scoped. Set `cloud: true` on a file target to add the `cloud` evidence section of `fallow inspect --cloud` (production data per local function). The CLI reads the key: `FALLOW_API_KEY` in the server environment, else the key that `fallow cloud login` stored; the key is never a parameter. `repo` (`owner/repo`) selects the repository and needs `cloud: true`. The section `status` is `ok`, `no_key`, `plan_required`, `unavailable` or `untracked`; a status other than `ok` never fails the call. `cloud: true` with a symbol target is refused. Set `format: "compact"` to get the plain text of `fallow inspect --format compact` (about 1 KB, no JSON) instead of the JSON bundle. Supports `root`, `config`, `production`, `workspace`, `include_churn`, `cloud`, `repo`, `format`, `no_cache`, and `threads`; `production` applies to trace, dead-code, and health evidence only. Raise `FALLOW_TIMEOUT_SECS` for large repos. |
@@ -1811,7 +1811,7 @@ export type MutationSchemaVersion = "2"
1811
1811
  /**
1812
1812
  * Why a run is partial.
1813
1813
  */
1814
- export type MutationIncompleteReason = ("runtime-error" | "mutant-limit" | "time-budget" | "skipped-files" | "unloaded-files" | "test-files-not-discovered" | "baseline-failure" | "worktree-changed" | "typecheck-failed" | "worktree-unchecked")
1814
+ export type MutationIncompleteReason = ("runtime-error" | "mutant-limit" | "sampled-out" | "time-budget" | "skipped-files" | "unloaded-files" | "test-files-not-discovered" | "baseline-failure" | "worktree-changed" | "typecheck-failed" | "worktree-unchecked")
1815
1815
  /**
1816
1816
  * The quality of observed test-to-mutant evidence.
1817
1817
  */
@@ -1832,6 +1832,10 @@ export type MutantStatus = ("killed" | "timeout" | "survived" | "no_coverage" |
1832
1832
  * How a run detected a mutant.
1833
1833
  */
1834
1834
  export type MutantFailureKind = ("assertion" | "error" | "timeout")
1835
+ /**
1836
+ * Why a survivor may be equivalent, as far as the type check can tell.
1837
+ */
1838
+ export type MutantEquivalenceHint = "type-non-nullish"
1835
1839
  /**
1836
1840
  * Why the type check did not check a survivor.
1837
1841
  */
@@ -2054,7 +2058,7 @@ diff_risk_introduced: number
2054
2058
  * The key set is OPEN. A name that a consumer does not recognize means "some
2055
2059
  * gate", not an error.
2056
2060
  *
2057
- * The names that this build can emit are `error-severity-findings`, `regression`, `stale-baseline`, `baseline-growth`, `duplication-threshold`, `duplication-findings`, `health-min-score`, `health-min-severity`, `health-findings`, `health-coverage-gaps`, `health-runtime-coverage`, `security`, `security-advisory`, `audit-verdict`, `type-aware-require` and `parse-error`. `GateName` describes each name and the default entries of each command.
2061
+ * The names that this build can emit are `error-severity-findings`, `regression`, `stale-baseline`, `baseline-growth`, `duplication-threshold`, `duplication-findings`, `health-min-score`, `health-min-severity`, `health-findings`, `health-coverage-gaps`, `health-runtime-coverage`, `security`, `security-advisory`, `audit-verdict`, `type-aware-require`, `parse-error` and `mutation-min-score`. `GateName` describes each name and the default entries of each command.
2058
2062
  */
2059
2063
  export interface GateOutcomes {
2060
2064
  [k: string]: GateOutcome
@@ -7928,11 +7932,11 @@ start_line: number
7928
7932
  */
7929
7933
  end_line: number
7930
7934
  /**
7931
- * 0-based start column.
7935
+ * 0-based byte column offset of the start.
7932
7936
  */
7933
7937
  start_col: number
7934
7938
  /**
7935
- * 0-based end column.
7939
+ * 0-based byte column offset of the end.
7936
7940
  */
7937
7941
  end_col: number
7938
7942
  /**
@@ -15236,11 +15240,11 @@ start_line: number
15236
15240
  */
15237
15241
  end_line: number
15238
15242
  /**
15239
- * 0-based start column.
15243
+ * 0-based byte column offset of the start.
15240
15244
  */
15241
15245
  start_col: number
15242
15246
  /**
15243
- * 0-based end column.
15247
+ * 0-based byte column offset of the end.
15244
15248
  */
15245
15249
  end_col: number
15246
15250
  /**
@@ -20731,6 +20735,12 @@ recheck?: (MutationRecheck | null)
20731
20735
  * `--compare`, and absent when this run is not complete.
20732
20736
  */
20733
20737
  compare?: (MutationCompare | null)
20738
+ /**
20739
+ * The verdict of the `mutation-min-score` gate. Present only when a
20740
+ * minimum applies: from `--min-score`, or from `mutation.minScore` when
20741
+ * the run is not a recheck. The exit code of the run reads this entry.
20742
+ */
20743
+ gate_outcomes?: (GateOutcomes | null)
20734
20744
  }
20735
20745
  /**
20736
20746
  * The completion status of a run.
@@ -20969,6 +20979,11 @@ score?: (number | null)
20969
20979
  * mutants never count. `null` when no mutant is covered or unreached.
20970
20980
  */
20971
20981
  coverage?: (number | null)
20982
+ /**
20983
+ * The `pending` mutants that the `--mutants-per-line` limit left out of
20984
+ * the plan. They are part of `counts.pending`.
20985
+ */
20986
+ sampled_out: number
20972
20987
  }
20973
20988
  /**
20974
20989
  * One mutant of a run.
@@ -21023,6 +21038,13 @@ status: MutantStatus
21023
21038
  * The static rule of a `pruned` mutant, kebab-case.
21024
21039
  */
21025
21040
  prune_reason?: (string | null)
21041
+ /**
21042
+ * Why a `pending` mutant did not run, kebab-case. Only `sampled-out` has
21043
+ * a reason: the `--mutants-per-line` limit left the mutant out of the
21044
+ * plan. A mutant that the mutant limit or the time budget left out has
21045
+ * no reason.
21046
+ */
21047
+ pending_reason?: (string | null)
21026
21048
  /**
21027
21049
  * The test that killed the mutant in this run. Absent for a kill by an
21028
21050
  * error outside a test.
@@ -21092,14 +21114,23 @@ resumed?: boolean
21092
21114
  * `compile_error` mutant, sorted, at most 8.
21093
21115
  */
21094
21116
  type_error_codes?: number[]
21117
+ /**
21118
+ * An advisory hint that the mutant may be equivalent to the original
21119
+ * code. The hint never changes the status: the mutant stays `survived`
21120
+ * and counts in the score. A person decides, and records the decision in
21121
+ * a verdict file. The hint can be wrong.
21122
+ */
21123
+ equivalence_hint?: (MutantEquivalenceHint | null)
21095
21124
  }
21096
21125
  /**
21097
21126
  * The edit of a mutant, without project text.
21098
21127
  *
21099
21128
  * Each side is an operator token (for example `??` or `<=`), a fixed literal
21100
21129
  * (`true`, `undefined`, `""`, `"fallow"`, `void 0`), a regular expression
21101
- * token (`^`, `$`, `[`, `[^`, `\d`), or a placeholder for a side that is
21102
- * project code: `<condition>`, `<call>`, `<expression>` or `<string>`. An
21130
+ * token (`^`, `$`, `[`, `[^`, `+`, `{n,m}`, `\d`), or a placeholder for a
21131
+ * side that is project code: `<condition>`, `<call>`, `<expression>`,
21132
+ * `<string>`, `<template>`, `<statement>`, `<statements>`, `<array>` or
21133
+ * `<object>`. An
21103
21134
  * empty side means that the edit removes the token.
21104
21135
  */
21105
21136
  export interface MutantChange {
@@ -21284,9 +21315,9 @@ changed_paths: string[]
21284
21315
  export interface MutationRunIssue {
21285
21316
  /**
21286
21317
  * A stable kebab-case code: `cache-write-failed`,
21287
- * `journal-write-failed`, `runtime-error`, `static-map-miss`,
21288
- * `test-files-not-discovered`, `typecheck-failed`, `worktree-changed`
21289
- * or `worktree-check-failed`.
21318
+ * `duplicate-test-ids`, `journal-write-failed`, `runtime-error`,
21319
+ * `skipped-tests`, `static-map-miss`, `test-files-not-discovered`,
21320
+ * `typecheck-failed`, `worktree-changed` or `worktree-check-failed`.
21290
21321
  */
21291
21322
  code: string
21292
21323
  /**
@@ -21401,6 +21432,12 @@ checked: number
21401
21432
  * `compile_error`.
21402
21433
  */
21403
21434
  compile_errors: number
21435
+ /**
21436
+ * The mutants of the final report that have an `equivalence_hint`. They
21437
+ * keep the status `survived`. A verdict that makes a mutant `equivalent`
21438
+ * removes its hint and lowers this count.
21439
+ */
21440
+ hinted?: number
21404
21441
  /**
21405
21442
  * The survivors that the checker did not check, by reason.
21406
21443
  */
@@ -21586,9 +21623,13 @@ total: number
21586
21623
  */
21587
21624
  planned: number
21588
21625
  /**
21589
- * Mutants after the mutant limit.
21626
+ * Mutants after the mutant limit, and the sampled-out mutants.
21590
21627
  */
21591
21628
  pending: number
21629
+ /**
21630
+ * The `pending` mutants that the `--mutants-per-line` limit left out.
21631
+ */
21632
+ sampled_out: number
21592
21633
  /**
21593
21634
  * Mutants that no test file reaches.
21594
21635
  */
@@ -21663,6 +21704,13 @@ disposition: MutationPlanDisposition
21663
21704
  * The static rule of a `pruned` mutant, kebab-case.
21664
21705
  */
21665
21706
  prune_reason?: (string | null)
21707
+ /**
21708
+ * Why a `pending` mutant did not run, kebab-case. Only `sampled-out` has
21709
+ * a reason: the `--mutants-per-line` limit left the mutant out of the
21710
+ * plan. A mutant that the mutant limit or the time budget left out has
21711
+ * no reason.
21712
+ */
21713
+ pending_reason?: (string | null)
21666
21714
  /**
21667
21715
  * How tests reach the code of the mutant in the module graph. Only a
21668
21716
  * `no_coverage` mutant has this field.
@@ -21864,6 +21912,12 @@ original_lines?: (string | null)
21864
21912
  * stale.
21865
21913
  */
21866
21914
  mutated_lines?: (string | null)
21915
+ /**
21916
+ * An advisory hint that the mutant may be equivalent. The task stays
21917
+ * open: a person decides, and records an equivalent mutant in a verdict
21918
+ * file.
21919
+ */
21920
+ equivalence_hint?: (MutantEquivalenceHint | null)
21867
21921
  /**
21868
21922
  * Why the current file no longer gives the mutant. Absent for a fresh
21869
21923
  * task.