fallow 3.33.0 → 3.34.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.33.0",
3
+ "version": "3.34.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": [
@@ -142,7 +142,7 @@
142
142
  "name": "--baseline",
143
143
  "type": "string",
144
144
  "required": false,
145
- "description": "Compare against a previously saved baseline file. Used by bare `fallow`, `dead-code`, `architecture`, `dupes` and `health`; other subcommands reject it"
145
+ "description": "Compare against a previously saved baseline file. Used by bare `fallow`, `dead-code`, `architecture`, `dupes` and `health`; other subcommands reject it. On bare `fallow` it holds the dead-code baseline only: pass health and duplication baselines with `--health-baseline` and `--dupes-baseline`"
146
146
  },
147
147
  {
148
148
  "name": "--baseline-mode",
@@ -164,7 +164,7 @@
164
164
  "name": "--save-baseline",
165
165
  "type": "string",
166
166
  "required": false,
167
- "description": "Save the current results as a baseline file. Used by bare `fallow`, `dead-code`, `architecture`, `dupes` and `health`; other subcommands reject it. The path must resolve inside the project root, its Git work tree, the CI workspace or a temp directory"
167
+ "description": "Save the current results as a baseline file. Used by bare `fallow`, `dead-code`, `architecture`, `dupes` and `health`; other subcommands reject it. On bare `fallow` it saves the dead-code baseline only: save the others with `fallow health --save-baseline` and `fallow dupes --save-baseline`. The path must resolve inside the project root, its Git work tree, the CI workspace or a temp directory"
168
168
  },
169
169
  {
170
170
  "name": "--production",
@@ -809,6 +809,36 @@
809
809
  "false"
810
810
  ]
811
811
  },
812
+ {
813
+ "name": "--unused-effect-layers",
814
+ "type": "bool",
815
+ "required": false,
816
+ "description": "Only report Effect layers composed only into unused layers",
817
+ "possible_values": [
818
+ "true",
819
+ "false"
820
+ ]
821
+ },
822
+ {
823
+ "name": "--unused-tagged-errors",
824
+ "type": "bool",
825
+ "required": false,
826
+ "description": "Only report Effect tagged errors that no code produces",
827
+ "possible_values": [
828
+ "true",
829
+ "false"
830
+ ]
831
+ },
832
+ {
833
+ "name": "--unproduced-catch-tags",
834
+ "type": "bool",
835
+ "required": false,
836
+ "description": "Only report catchTag handlers for a tag that no code produces",
837
+ "possible_values": [
838
+ "true",
839
+ "false"
840
+ ]
841
+ },
812
842
  {
813
843
  "name": "--unused-server-actions",
814
844
  "type": "bool",
@@ -1151,6 +1181,116 @@
1151
1181
  }
1152
1182
  ]
1153
1183
  },
1184
+ {
1185
+ "name": "mutation",
1186
+ "description": "Measure how well the tests detect changes in the code (opt-in)",
1187
+ "flags": [
1188
+ {
1189
+ "name": "--all",
1190
+ "type": "bool",
1191
+ "required": false,
1192
+ "description": "Mutate every source file instead of the changed code",
1193
+ "possible_values": [
1194
+ "true",
1195
+ "false"
1196
+ ]
1197
+ },
1198
+ {
1199
+ "name": "--plan",
1200
+ "type": "bool",
1201
+ "required": false,
1202
+ "description": "Build the plan only: select, map and rank mutants. Runs no code",
1203
+ "possible_values": [
1204
+ "true",
1205
+ "false"
1206
+ ]
1207
+ },
1208
+ {
1209
+ "name": "--max-mutants",
1210
+ "type": "string",
1211
+ "required": false,
1212
+ "description": "Run at most N covered mutants, in rank order. Uncovered mutants do not count. The others are `pending`"
1213
+ },
1214
+ {
1215
+ "name": "--time-budget",
1216
+ "type": "string",
1217
+ "required": false,
1218
+ "description": "Stop starting mutants after this time, for example `90s`, `10m` or `1h`. The others are `pending`"
1219
+ },
1220
+ {
1221
+ "name": "--concurrency",
1222
+ "type": "string",
1223
+ "required": false,
1224
+ "description": "The number of companion processes (default: half the logical cores)"
1225
+ },
1226
+ {
1227
+ "name": "--runtime",
1228
+ "type": "string",
1229
+ "required": false,
1230
+ "description": "The JavaScript runtime (default from PATH: `node` for node:test, `bun` for bun test, and `node`, then `bun`, for Vitest)"
1231
+ },
1232
+ {
1233
+ "name": "--allow-dirty",
1234
+ "type": "bool",
1235
+ "required": false,
1236
+ "description": "Run in a dirty git worktree. The run still reports the paths that it changed",
1237
+ "possible_values": [
1238
+ "true",
1239
+ "false"
1240
+ ]
1241
+ },
1242
+ {
1243
+ "name": "--allow-side-effects",
1244
+ "type": "bool",
1245
+ "required": false,
1246
+ "description": "Keep mutants in functions that reach a file system, process, network or database sink. A mutant can then remove a guard of a real side effect. This is a flag only, never a config key",
1247
+ "possible_values": [
1248
+ "true",
1249
+ "false"
1250
+ ]
1251
+ },
1252
+ {
1253
+ "name": "--min-score",
1254
+ "type": "string",
1255
+ "required": false,
1256
+ "description": "Exit with code 1 when the mutation score is below this percentage"
1257
+ },
1258
+ {
1259
+ "name": "--operators",
1260
+ "type": "string",
1261
+ "required": false,
1262
+ "description": "The operators to use, comma-separated (default: each operator)"
1263
+ },
1264
+ {
1265
+ "name": "--verdicts",
1266
+ "type": "string",
1267
+ "required": false,
1268
+ "description": "A verdict document that marks mutants as equivalent. Equivalent mutants leave the score"
1269
+ },
1270
+ {
1271
+ "name": "--setup-timeout",
1272
+ "type": "string",
1273
+ "required": false,
1274
+ "description": "Wait this long for each runner process to start, finish its dry run or reload, for example `5m` on a slow or busy host (default: `2m`)"
1275
+ },
1276
+ {
1277
+ "name": "--typecheck",
1278
+ "type": "bool",
1279
+ "required": false,
1280
+ "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",
1281
+ "possible_values": [
1282
+ "true",
1283
+ "false"
1284
+ ]
1285
+ },
1286
+ {
1287
+ "name": "paths",
1288
+ "type": "string",
1289
+ "required": false,
1290
+ "description": "Mutate only these files or directories instead of the changed code"
1291
+ }
1292
+ ]
1293
+ },
1154
1294
  {
1155
1295
  "name": "inspect",
1156
1296
  "description": "Inspect one file or exported symbol as a bundled evidence query",
@@ -1916,6 +2056,12 @@
1916
2056
  "required": false,
1917
2057
  "description": "File or directory containing runtime coverage input. Accepts a V8 coverage directory, a single V8 JSON file, or a single Istanbul coverage map JSON file (commonly coverage-final.json). A single local capture is free. Continuous or multi-capture monitoring needs a license (see `fallow license`)"
1918
2058
  },
2059
+ {
2060
+ "name": "--mutation-report",
2061
+ "type": "string",
2062
+ "required": false,
2063
+ "description": "Saved `fallow mutation --format json` report (for example `.fallow/mutation/last-report.json` or the `-o` file of a run). Adds the mutation score of each complexity finding next to its CRAP score. The score never changes CRAP or the health score. A function whose file changed since the run gets no score. Reads the file only; it runs no test"
2064
+ },
1919
2065
  {
1920
2066
  "name": "--min-invocations-hot",
1921
2067
  "type": "string",
@@ -2120,6 +2266,30 @@
2120
2266
  "required": false,
2121
2267
  "description": "Absolute prefix to strip from coverage data paths before CRAP matching. Use when coverage was generated under a different checkout root in CI or Docker. Also configurable via FALLOW_COVERAGE_ROOT or health.coverageRoot"
2122
2268
  },
2269
+ {
2270
+ "name": "--only",
2271
+ "type": "string",
2272
+ "required": false,
2273
+ "description": "Run only these sub-analyses (comma-separated: dead-code, architecture, dupes, health), with the same values as bare `fallow --only`. Replaces the `audit.deadCode`, `audit.health` and `audit.dupes` selection. The review brief (`--brief`, `fallow review`) keeps every sub-analysis",
2274
+ "possible_values": [
2275
+ "dead-code",
2276
+ "dupes",
2277
+ "health",
2278
+ "architecture"
2279
+ ]
2280
+ },
2281
+ {
2282
+ "name": "--skip",
2283
+ "type": "string",
2284
+ "required": false,
2285
+ "description": "Skip these sub-analyses (comma-separated: dead-code, architecture, dupes, health), with the same values as bare `fallow --skip`, on top of the `audit.*` selection",
2286
+ "possible_values": [
2287
+ "dead-code",
2288
+ "dupes",
2289
+ "health",
2290
+ "architecture"
2291
+ ]
2292
+ },
2123
2293
  {
2124
2294
  "name": "--no-css",
2125
2295
  "type": "bool",
@@ -3455,7 +3625,7 @@
3455
3625
  "description": "Suppression comment or tag no longer matches any issue",
3456
3626
  "label": "Stale Suppressions",
3457
3627
  "config_key": "stale-suppressions",
3458
- "registry_index": 40,
3628
+ "registry_index": 43,
3459
3629
  "aliases": [],
3460
3630
  "lsp": true,
3461
3631
  "filter_flag": "--stale-suppressions",
@@ -3491,7 +3661,7 @@
3491
3661
  "description": "Suppression comment omits a required reason",
3492
3662
  "label": "Missing Suppression Reasons",
3493
3663
  "config_key": "require-suppression-reason",
3494
- "registry_index": 41,
3664
+ "registry_index": 44,
3495
3665
  "aliases": [
3496
3666
  "missing-suppression-reasons"
3497
3667
  ],
@@ -3523,7 +3693,7 @@
3523
3693
  "description": "Catalog entry not referenced by any workspace package",
3524
3694
  "label": "Unused Catalog Entries",
3525
3695
  "config_key": "unused-catalog-entries",
3526
- "registry_index": 42,
3696
+ "registry_index": 45,
3527
3697
  "aliases": [
3528
3698
  "catalog",
3529
3699
  "unused-catalog-entries"
@@ -3563,7 +3733,7 @@
3563
3733
  "description": "Named catalog group has no entries",
3564
3734
  "label": "Empty Catalog Groups",
3565
3735
  "config_key": "empty-catalog-groups",
3566
- "registry_index": 43,
3736
+ "registry_index": 46,
3567
3737
  "aliases": [
3568
3738
  "empty-catalog",
3569
3739
  "empty-catalog-groups"
@@ -3603,7 +3773,7 @@
3603
3773
  "description": "package.json references a catalog that does not declare the package",
3604
3774
  "label": "Unresolved Catalog References",
3605
3775
  "config_key": "unresolved-catalog-references",
3606
- "registry_index": 44,
3776
+ "registry_index": 47,
3607
3777
  "aliases": [
3608
3778
  "unresolved-catalog",
3609
3779
  "unresolved-catalog-references"
@@ -3643,7 +3813,7 @@
3643
3813
  "description": "Package-manager override target is not declared or resolved",
3644
3814
  "label": "Unused Dependency Overrides",
3645
3815
  "config_key": "unused-dependency-overrides",
3646
- "registry_index": 45,
3816
+ "registry_index": 48,
3647
3817
  "aliases": [
3648
3818
  "unused-dependency-overrides",
3649
3819
  "unused-override",
@@ -3684,7 +3854,7 @@
3684
3854
  "description": "Package-manager override has an unparsable key or value",
3685
3855
  "label": "Misconfigured Dependency Overrides",
3686
3856
  "config_key": "misconfigured-dependency-overrides",
3687
- "registry_index": 46,
3857
+ "registry_index": 49,
3688
3858
  "aliases": [
3689
3859
  "misconfigured-dependency-overrides",
3690
3860
  "misconfigured-override",
@@ -4115,6 +4285,114 @@
4115
4285
  "license_note": null,
4116
4286
  "docs_url": "https://fallow.tools/docs/explanations/dead-code/#unused-svelte-events"
4117
4287
  },
4288
+ {
4289
+ "id": "unused-effect-layer",
4290
+ "rule_id": "fallow/unused-effect-layer",
4291
+ "command": "dead-code",
4292
+ "category": "Dead code",
4293
+ "description": "An Effect layer is composed only into layers that nothing uses",
4294
+ "label": "Unused Effect Layers",
4295
+ "config_key": "unused-effect-layers",
4296
+ "registry_index": 38,
4297
+ "aliases": [
4298
+ "unused-effect-layers"
4299
+ ],
4300
+ "lsp": true,
4301
+ "filter_flag": "--unused-effect-layers",
4302
+ "result_key": "unused_effect_layers",
4303
+ "summary_label": "Unused Effect layers",
4304
+ "summary_docs_anchor": "unused-effect-layers",
4305
+ "sarif_rule_ids": [
4306
+ "fallow/unused-effect-layer"
4307
+ ],
4308
+ "codeclimate_check_names": [
4309
+ "fallow/unused-effect-layer"
4310
+ ],
4311
+ "ts_alias": null,
4312
+ "counts_in_total": true,
4313
+ "fixable": false,
4314
+ "suppressible": true,
4315
+ "suppress_comment": "// fallow-ignore-next-line unused-effect-layer",
4316
+ "default_severity": "warn",
4317
+ "opt_in": false,
4318
+ "frameworks": [],
4319
+ "note": null,
4320
+ "license": "free",
4321
+ "license_note": null,
4322
+ "docs_url": "https://fallow.tools/docs/explanations/dead-code/#unused-effect-layers"
4323
+ },
4324
+ {
4325
+ "id": "unused-tagged-error",
4326
+ "rule_id": "fallow/unused-tagged-error",
4327
+ "command": "dead-code",
4328
+ "category": "Dead code",
4329
+ "description": "An Effect tagged error class is referenced only as a type or a catchTag string, and no code constructs or fails with it",
4330
+ "label": "Unused Tagged Errors",
4331
+ "config_key": "unused-tagged-errors",
4332
+ "registry_index": 39,
4333
+ "aliases": [
4334
+ "unused-tagged-errors"
4335
+ ],
4336
+ "lsp": true,
4337
+ "filter_flag": "--unused-tagged-errors",
4338
+ "result_key": "unused_tagged_errors",
4339
+ "summary_label": "Unused tagged errors",
4340
+ "summary_docs_anchor": "unused-tagged-errors",
4341
+ "sarif_rule_ids": [
4342
+ "fallow/unused-tagged-error"
4343
+ ],
4344
+ "codeclimate_check_names": [
4345
+ "fallow/unused-tagged-error"
4346
+ ],
4347
+ "ts_alias": null,
4348
+ "counts_in_total": true,
4349
+ "fixable": false,
4350
+ "suppressible": true,
4351
+ "suppress_comment": "// fallow-ignore-next-line unused-tagged-error",
4352
+ "default_severity": "warn",
4353
+ "opt_in": false,
4354
+ "frameworks": [],
4355
+ "note": null,
4356
+ "license": "free",
4357
+ "license_note": null,
4358
+ "docs_url": "https://fallow.tools/docs/explanations/dead-code/#unused-tagged-errors"
4359
+ },
4360
+ {
4361
+ "id": "unproduced-catch-tag",
4362
+ "rule_id": "fallow/unproduced-catch-tag",
4363
+ "command": "dead-code",
4364
+ "category": "Dead code",
4365
+ "description": "A catchTag handler names a project error tag that no code produces",
4366
+ "label": "Unproduced Catch Tags",
4367
+ "config_key": "unproduced-catch-tags",
4368
+ "registry_index": 40,
4369
+ "aliases": [
4370
+ "unproduced-catch-tags"
4371
+ ],
4372
+ "lsp": true,
4373
+ "filter_flag": "--unproduced-catch-tags",
4374
+ "result_key": "unproduced_catch_tags",
4375
+ "summary_label": "Unproduced catch tags",
4376
+ "summary_docs_anchor": "unproduced-catch-tags",
4377
+ "sarif_rule_ids": [
4378
+ "fallow/unproduced-catch-tag"
4379
+ ],
4380
+ "codeclimate_check_names": [
4381
+ "fallow/unproduced-catch-tag"
4382
+ ],
4383
+ "ts_alias": null,
4384
+ "counts_in_total": true,
4385
+ "fixable": false,
4386
+ "suppressible": true,
4387
+ "suppress_comment": "// fallow-ignore-next-line unproduced-catch-tag",
4388
+ "default_severity": "warn",
4389
+ "opt_in": false,
4390
+ "frameworks": [],
4391
+ "note": null,
4392
+ "license": "free",
4393
+ "license_note": null,
4394
+ "docs_url": "https://fallow.tools/docs/explanations/dead-code/#unproduced-catch-tags"
4395
+ },
4118
4396
  {
4119
4397
  "id": "unused-server-action",
4120
4398
  "rule_id": "fallow/unused-server-action",
@@ -4195,7 +4473,7 @@
4195
4473
  "description": "A React/Preact prop is forwarded unchanged through 3+ pass-through components to a distant consumer",
4196
4474
  "label": "Prop Drilling",
4197
4475
  "config_key": "prop-drilling",
4198
- "registry_index": 52,
4476
+ "registry_index": 55,
4199
4477
  "aliases": [],
4200
4478
  "lsp": true,
4201
4479
  "filter_flag": null,
@@ -4205,16 +4483,18 @@
4205
4483
  "sarif_rule_ids": [
4206
4484
  "fallow/prop-drilling"
4207
4485
  ],
4208
- "codeclimate_check_names": null,
4486
+ "codeclimate_check_names": [
4487
+ "fallow/prop-drilling"
4488
+ ],
4209
4489
  "ts_alias": null,
4210
- "counts_in_total": false,
4490
+ "counts_in_total": true,
4211
4491
  "fixable": false,
4212
4492
  "suppressible": true,
4213
4493
  "suppress_comment": "// fallow-ignore-next-line prop-drilling",
4214
4494
  "default_severity": "off",
4215
4495
  "opt_in": true,
4216
4496
  "frameworks": [],
4217
- "note": "Opt-in: set rules.prop-drilling to warn or error to enable. Defaults to off.",
4497
+ "note": "Opt-in: error gates CI; warn remains advisory even with --fail-on-issues. Defaults to off. Source-hop overrides decide severity.",
4218
4498
  "license": "free",
4219
4499
  "license_note": null,
4220
4500
  "docs_url": "https://fallow.tools/docs/explanations/dead-code/#prop-drilling"
@@ -4227,7 +4507,7 @@
4227
4507
  "description": "A React/Preact component whose whole body is a single spread-forwarded child render (a candidate for inlining)",
4228
4508
  "label": "Thin Wrappers",
4229
4509
  "config_key": "thin-wrapper",
4230
- "registry_index": 53,
4510
+ "registry_index": 56,
4231
4511
  "aliases": [
4232
4512
  "thin-wrappers"
4233
4513
  ],
@@ -4261,7 +4541,7 @@
4261
4541
  "description": "Three or more React/Preact components across two or more files declare an identical prop-name set (a missing shared Props type)",
4262
4542
  "label": "Duplicate Prop Shapes",
4263
4543
  "config_key": "duplicate-prop-shape",
4264
- "registry_index": 54,
4544
+ "registry_index": 57,
4265
4545
  "aliases": [
4266
4546
  "duplicate-prop-shapes"
4267
4547
  ],
@@ -4295,7 +4575,7 @@
4295
4575
  "description": "Two or more Next.js App Router route files resolve to the same URL",
4296
4576
  "label": "Route Collisions",
4297
4577
  "config_key": "route-collision",
4298
- "registry_index": 38,
4578
+ "registry_index": 41,
4299
4579
  "aliases": [
4300
4580
  "route-collisions"
4301
4581
  ],
@@ -4333,7 +4613,7 @@
4333
4613
  "description": "Sibling Next.js dynamic route segments use different slug names at the same position",
4334
4614
  "label": "Dynamic Segment Conflicts",
4335
4615
  "config_key": "dynamic-segment-name-conflict",
4336
- "registry_index": 39,
4616
+ "registry_index": 42,
4337
4617
  "aliases": [
4338
4618
  "dynamic-segment-name-conflicts"
4339
4619
  ],
@@ -4521,7 +4801,7 @@
4521
4801
  "description": "CSS or CSS-in-JS hardcoded styling value bypasses the design token system",
4522
4802
  "label": "CSS Token Drift",
4523
4803
  "config_key": "css-token-drift",
4524
- "registry_index": 55,
4804
+ "registry_index": 58,
4525
4805
  "aliases": [],
4526
4806
  "lsp": false,
4527
4807
  "filter_flag": null,
@@ -4551,7 +4831,7 @@
4551
4831
  "description": "CSS or CSS-in-JS declaration block is duplicated across rules",
4552
4832
  "label": "CSS Duplicate Block",
4553
4833
  "config_key": "css-duplicate-block",
4554
- "registry_index": 56,
4834
+ "registry_index": 59,
4555
4835
  "aliases": [],
4556
4836
  "lsp": false,
4557
4837
  "filter_flag": null,
@@ -4581,7 +4861,7 @@
4581
4861
  "description": "CSS selector, nesting, or important usage is structurally complex",
4582
4862
  "label": "CSS Selector Complexity",
4583
4863
  "config_key": "css-selector-complexity",
4584
- "registry_index": 57,
4864
+ "registry_index": 60,
4585
4865
  "aliases": [],
4586
4866
  "lsp": false,
4587
4867
  "filter_flag": null,
@@ -4611,7 +4891,7 @@
4611
4891
  "description": "CSS or CSS-in-JS surface appears unused",
4612
4892
  "label": "CSS Dead Surface",
4613
4893
  "config_key": "css-dead-surface",
4614
- "registry_index": 58,
4894
+ "registry_index": 61,
4615
4895
  "aliases": [],
4616
4896
  "lsp": false,
4617
4897
  "filter_flag": null,
@@ -4641,7 +4921,7 @@
4641
4921
  "description": "CSS or CSS-in-JS reference resolves to no stylesheet definition",
4642
4922
  "label": "CSS Broken Reference",
4643
4923
  "config_key": "css-broken-reference",
4644
- "registry_index": 59,
4924
+ "registry_index": 62,
4645
4925
  "aliases": [],
4646
4926
  "lsp": false,
4647
4927
  "filter_flag": null,
@@ -5031,7 +5311,7 @@
5031
5311
  "description": "Detected feature flag pattern",
5032
5312
  "label": "Feature Flags",
5033
5313
  "config_key": "feature-flags",
5034
- "registry_index": 50,
5314
+ "registry_index": 53,
5035
5315
  "aliases": [],
5036
5316
  "lsp": false,
5037
5317
  "filter_flag": null,
@@ -6522,6 +6802,156 @@
6522
6802
  "license": "free",
6523
6803
  "license_note": null,
6524
6804
  "docs_url": "https://fallow.tools/docs/cli/security/"
6805
+ },
6806
+ {
6807
+ "id": "weakened-tests",
6808
+ "rule_id": "fallow/weakened-tests",
6809
+ "command": "audit",
6810
+ "category": "Audit",
6811
+ "description": "The change weakens tests or a coverage threshold",
6812
+ "label": "Weakened Tests",
6813
+ "config_key": "weakened-tests",
6814
+ "registry_index": 63,
6815
+ "aliases": [],
6816
+ "lsp": false,
6817
+ "filter_flag": null,
6818
+ "result_key": null,
6819
+ "summary_label": null,
6820
+ "summary_docs_anchor": null,
6821
+ "sarif_rule_ids": null,
6822
+ "codeclimate_check_names": null,
6823
+ "ts_alias": null,
6824
+ "counts_in_total": false,
6825
+ "fixable": false,
6826
+ "suppressible": true,
6827
+ "suppress_comment": "// fallow-ignore-next-line weakened-tests",
6828
+ "default_severity": "warn",
6829
+ "opt_in": false,
6830
+ "frameworks": [],
6831
+ "note": null,
6832
+ "license": "free",
6833
+ "license_note": null,
6834
+ "docs_url": "https://fallow.tools/docs/cli/audit/#diff-risk-rules"
6835
+ },
6836
+ {
6837
+ "id": "added-suppression",
6838
+ "rule_id": "fallow/added-suppression",
6839
+ "command": "audit",
6840
+ "category": "Audit",
6841
+ "description": "The change adds a suppression comment",
6842
+ "label": "Added Suppressions",
6843
+ "config_key": "added-suppression",
6844
+ "registry_index": 64,
6845
+ "aliases": [],
6846
+ "lsp": false,
6847
+ "filter_flag": null,
6848
+ "result_key": null,
6849
+ "summary_label": null,
6850
+ "summary_docs_anchor": null,
6851
+ "sarif_rule_ids": null,
6852
+ "codeclimate_check_names": null,
6853
+ "ts_alias": null,
6854
+ "counts_in_total": false,
6855
+ "fixable": false,
6856
+ "suppressible": true,
6857
+ "suppress_comment": "// fallow-ignore-next-line added-suppression",
6858
+ "default_severity": "warn",
6859
+ "opt_in": false,
6860
+ "frameworks": [],
6861
+ "note": null,
6862
+ "license": "free",
6863
+ "license_note": null,
6864
+ "docs_url": "https://fallow.tools/docs/cli/audit/#diff-risk-rules"
6865
+ },
6866
+ {
6867
+ "id": "test-only-branch",
6868
+ "rule_id": "fallow/test-only-branch",
6869
+ "command": "audit",
6870
+ "category": "Audit",
6871
+ "description": "The change adds a test-environment branch to source code",
6872
+ "label": "Test-Only Branches",
6873
+ "config_key": "test-only-branch",
6874
+ "registry_index": 65,
6875
+ "aliases": [],
6876
+ "lsp": false,
6877
+ "filter_flag": null,
6878
+ "result_key": null,
6879
+ "summary_label": null,
6880
+ "summary_docs_anchor": null,
6881
+ "sarif_rule_ids": null,
6882
+ "codeclimate_check_names": null,
6883
+ "ts_alias": null,
6884
+ "counts_in_total": false,
6885
+ "fixable": false,
6886
+ "suppressible": true,
6887
+ "suppress_comment": "// fallow-ignore-next-line test-only-branch",
6888
+ "default_severity": "warn",
6889
+ "opt_in": false,
6890
+ "frameworks": [],
6891
+ "note": null,
6892
+ "license": "free",
6893
+ "license_note": null,
6894
+ "docs_url": "https://fallow.tools/docs/cli/audit/#diff-risk-rules"
6895
+ },
6896
+ {
6897
+ "id": "diverged-clone-sibling",
6898
+ "rule_id": "fallow/diverged-clone-sibling",
6899
+ "command": "audit",
6900
+ "category": "Audit",
6901
+ "description": "The change edits one copy of duplicated code but not its siblings",
6902
+ "label": "Diverged Clone Siblings",
6903
+ "config_key": "diverged-clone-sibling",
6904
+ "registry_index": 66,
6905
+ "aliases": [],
6906
+ "lsp": false,
6907
+ "filter_flag": null,
6908
+ "result_key": null,
6909
+ "summary_label": null,
6910
+ "summary_docs_anchor": null,
6911
+ "sarif_rule_ids": null,
6912
+ "codeclimate_check_names": null,
6913
+ "ts_alias": null,
6914
+ "counts_in_total": false,
6915
+ "fixable": false,
6916
+ "suppressible": true,
6917
+ "suppress_comment": "// fallow-ignore-next-line diverged-clone-sibling",
6918
+ "default_severity": "off",
6919
+ "opt_in": true,
6920
+ "frameworks": [],
6921
+ "note": null,
6922
+ "license": "free",
6923
+ "license_note": null,
6924
+ "docs_url": "https://fallow.tools/docs/cli/audit/#diff-risk-rules"
6925
+ },
6926
+ {
6927
+ "id": "added-dependency",
6928
+ "rule_id": "fallow/added-dependency",
6929
+ "command": "audit",
6930
+ "category": "Audit",
6931
+ "description": "The change adds a dependency",
6932
+ "label": "Added Dependencies",
6933
+ "config_key": "added-dependency",
6934
+ "registry_index": 67,
6935
+ "aliases": [],
6936
+ "lsp": false,
6937
+ "filter_flag": null,
6938
+ "result_key": null,
6939
+ "summary_label": null,
6940
+ "summary_docs_anchor": null,
6941
+ "sarif_rule_ids": null,
6942
+ "codeclimate_check_names": null,
6943
+ "ts_alias": null,
6944
+ "counts_in_total": false,
6945
+ "fixable": false,
6946
+ "suppressible": false,
6947
+ "suppress_comment": null,
6948
+ "default_severity": "off",
6949
+ "opt_in": true,
6950
+ "frameworks": [],
6951
+ "note": null,
6952
+ "license": "free",
6953
+ "license_note": null,
6954
+ "docs_url": "https://fallow.tools/docs/cli/audit/#diff-risk-rules"
6525
6955
  }
6526
6956
  ],
6527
6957
  "suppression_comments": {
@@ -6743,9 +7173,9 @@
6743
7173
  "first_run": false,
6744
7174
  "framework_gated": false,
6745
7175
  "config_paths": [
6746
- "health.maxCyclomaticComplexity",
6747
- "health.maxCognitiveComplexity",
6748
- "health.maxCrapThreshold",
7176
+ "health.maxCyclomatic",
7177
+ "health.maxCognitive",
7178
+ "health.maxCrap",
6749
7179
  "health.maxUnitSize"
6750
7180
  ],
6751
7181
  "default_summary": "cyclomatic 20, cognitive 15, CRAP 30, unit size 60 lines. These are SIG-aligned; raise them for an established codebase that would otherwise report a large existing backlog.",
@@ -7207,6 +7637,37 @@
7207
7637
  "read_only": true,
7208
7638
  "code_mode_alias": null
7209
7639
  },
7640
+ {
7641
+ "name": "mutation_plan",
7642
+ "kind": "analysis",
7643
+ "description": "Static mutation plan for changed code: mutant ids, operators, dispositions, and static test files; runs no tests",
7644
+ "cli_command": "fallow mutation --plan --format json --quiet",
7645
+ "key_params": [
7646
+ "changed_since",
7647
+ "all",
7648
+ "paths",
7649
+ "max_mutants",
7650
+ "operators"
7651
+ ],
7652
+ "license": "free",
7653
+ "license_note": null,
7654
+ "read_only": true,
7655
+ "code_mode_alias": null
7656
+ },
7657
+ {
7658
+ "name": "mutation_inspect",
7659
+ "kind": "trace",
7660
+ "description": "Inspect one mutant of a saved mutation report (default: the last run report), with a stale status when its source changed; runs no tests",
7661
+ "cli_command": "fallow mutation inspect <mutant-id> [--report <report.json>] --format json --quiet",
7662
+ "key_params": [
7663
+ "mutant_id",
7664
+ "report"
7665
+ ],
7666
+ "license": "free",
7667
+ "license_note": null,
7668
+ "read_only": true,
7669
+ "code_mode_alias": null
7670
+ },
7210
7671
  {
7211
7672
  "name": "inspect_target",
7212
7673
  "kind": "analysis",
@@ -7412,11 +7873,12 @@
7412
7873
  {
7413
7874
  "name": "audit",
7414
7875
  "kind": "analysis",
7415
- "description": "Combined dead-code, complexity, duplication, and styling audit for changed files with a pass/warn/fail verdict",
7876
+ "description": "Combined dead-code, complexity, duplication, styling, and diff-risk audit for changed files with a pass/warn/fail verdict. The diff-risk rules are weakened-tests, added-suppression, test-only-branch, diverged-clone-sibling, and added-dependency",
7416
7877
  "cli_command": "fallow audit --format json --quiet",
7417
7878
  "key_params": [
7418
7879
  "gate",
7419
7880
  "base",
7881
+ "skip",
7420
7882
  "css_deep",
7421
7883
  "max_crap",
7422
7884
  "coverage",
@@ -7801,7 +8263,7 @@
7801
8263
  ]
7802
8264
  },
7803
8265
  "plugins": {
7804
- "count": 134,
8266
+ "count": 145,
7805
8267
  "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",
7806
8268
  "names": [
7807
8269
  "nextjs",
@@ -7878,6 +8340,8 @@
7878
8340
  "karma",
7879
8341
  "cucumber",
7880
8342
  "webdriverio",
8343
+ "jasmine",
8344
+ "rstest",
7881
8345
  "eslint",
7882
8346
  "biome",
7883
8347
  "stylelint",
@@ -7899,6 +8363,8 @@
7899
8363
  "knex",
7900
8364
  "typeorm",
7901
8365
  "kysely",
8366
+ "textlint",
8367
+ "typescript-content-mapper",
7902
8368
  "turborepo",
7903
8369
  "nx",
7904
8370
  "changesets",
@@ -7912,8 +8378,10 @@
7912
8378
  "hardhat",
7913
8379
  "vercel",
7914
8380
  "wrangler",
8381
+ "alchemy",
7915
8382
  "opennext-cloudflare",
7916
8383
  "sentry",
8384
+ "opentelemetry",
7917
8385
  "husky",
7918
8386
  "lint-staged",
7919
8387
  "lefthook",
@@ -7937,7 +8405,12 @@
7937
8405
  "varlock",
7938
8406
  "pnpm",
7939
8407
  "bun",
7940
- "deno"
8408
+ "deno",
8409
+ "mise",
8410
+ "railway",
8411
+ "serverless-framework",
8412
+ "osls",
8413
+ "flue"
7941
8414
  ]
7942
8415
  },
7943
8416
  "task_matrix": [