fallow 3.26.0 → 3.27.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.26.0",
3
+ "version": "3.27.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": [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "3.26.0",
3
+ "version": "3.27.0",
4
4
  "mcpName": "io.github.fallow-rs/fallow",
5
5
  "description": "Codebase intelligence for TypeScript and JavaScript. Free static analysis of code and styles, optional paid runtime intelligence (Fallow Runtime). Quality, risk, architecture, dependencies, duplication, and design-system drift for humans, CI, and the agents writing your code. Zero-config framework support.",
6
6
  "license": "MIT",
@@ -85,17 +85,17 @@
85
85
  "detect-libc": "2.1.2"
86
86
  },
87
87
  "devDependencies": {
88
- "@tanstack/intent": "0.3.8"
88
+ "@tanstack/intent": "0.4.0"
89
89
  },
90
90
  "optionalDependencies": {
91
- "@fallow-cli/darwin-arm64": "3.26.0",
92
- "@fallow-cli/darwin-x64": "3.26.0",
93
- "@fallow-cli/linux-x64-gnu": "3.26.0",
94
- "@fallow-cli/linux-arm64-gnu": "3.26.0",
95
- "@fallow-cli/linux-x64-musl": "3.26.0",
96
- "@fallow-cli/linux-arm64-musl": "3.26.0",
97
- "@fallow-cli/win32-arm64-msvc": "3.26.0",
98
- "@fallow-cli/win32-x64-msvc": "3.26.0",
99
- "fallow-type-aware": "3.26.0"
91
+ "@fallow-cli/darwin-arm64": "3.27.0",
92
+ "@fallow-cli/darwin-x64": "3.27.0",
93
+ "@fallow-cli/linux-x64-gnu": "3.27.0",
94
+ "@fallow-cli/linux-arm64-gnu": "3.27.0",
95
+ "@fallow-cli/linux-x64-musl": "3.27.0",
96
+ "@fallow-cli/linux-arm64-musl": "3.27.0",
97
+ "@fallow-cli/win32-arm64-msvc": "3.27.0",
98
+ "@fallow-cli/win32-x64-msvc": "3.27.0",
99
+ "fallow-type-aware": "3.27.0"
100
100
  }
101
101
  }
@@ -446,7 +446,7 @@ Human output groups paths under "Shared with your team (commit these)" and "Loca
446
446
  {
447
447
  "kind": "agent-install",
448
448
  "schema_version": 1,
449
- "fallow_version": "3.26.0",
449
+ "fallow_version": "3.27.0",
450
450
  "root": "/abs/path",
451
451
  "mode": "install",
452
452
  "dry_run": false,
@@ -650,7 +650,7 @@ fallow health --format json --quiet --trend
650
650
  {
651
651
  "kind": "health",
652
652
  "schema_version": 7,
653
- "version": "3.26.0",
653
+ "version": "3.27.0",
654
654
  "elapsed_ms": 32,
655
655
  "summary": {
656
656
  "files_analyzed": 482,
@@ -1053,7 +1053,7 @@ fallow audit \
1053
1053
  {
1054
1054
  "kind": "audit",
1055
1055
  "schema_version": 7,
1056
- "version": "3.26.0",
1056
+ "version": "3.27.0",
1057
1057
  "command": "audit",
1058
1058
  "verdict": "fail",
1059
1059
  "changed_files_count": 12,
@@ -1130,7 +1130,7 @@ fallow flags --format json --quiet --workspace my-package
1130
1130
  ```json
1131
1131
  {
1132
1132
  "schema_version": 7,
1133
- "version": "3.26.0",
1133
+ "version": "3.27.0",
1134
1134
  "elapsed_ms": 116,
1135
1135
  "feature_flags": [],
1136
1136
  "total_flags": 0
@@ -1231,7 +1231,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1231
1231
  {
1232
1232
  "kind": "security",
1233
1233
  "schema_version": "4",
1234
- "version": "3.26.0",
1234
+ "version": "3.27.0",
1235
1235
  "elapsed_ms": 42,
1236
1236
  "config": {
1237
1237
  "rules": {
@@ -1260,7 +1260,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1260
1260
  {
1261
1261
  "kind": "security",
1262
1262
  "schema_version": "4",
1263
- "version": "3.26.0",
1263
+ "version": "3.27.0",
1264
1264
  "elapsed_ms": 42,
1265
1265
  "config": {
1266
1266
  "rules": {
@@ -2030,7 +2030,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
2030
2030
  {
2031
2031
  "kind": "dead-code",
2032
2032
  "schema_version": 7,
2033
- "version": "3.26.0",
2033
+ "version": "3.27.0",
2034
2034
  "elapsed_ms": 45,
2035
2035
  "total_issues": 12,
2036
2036
  "entry_points": {
@@ -2190,7 +2190,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
2190
2190
  {
2191
2191
  "kind": "dupes",
2192
2192
  "schema_version": 7,
2193
- "version": "3.26.0",
2193
+ "version": "3.27.0",
2194
2194
  "elapsed_ms": 82,
2195
2195
  "total_clones": 15,
2196
2196
  "total_lines_duplicated": 230,
@@ -2234,11 +2234,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
2234
2234
  {
2235
2235
  "kind": "combined",
2236
2236
  "schema_version": 7,
2237
- "version": "3.26.0",
2237
+ "version": "3.27.0",
2238
2238
  "elapsed_ms": 159,
2239
2239
  "check": {
2240
2240
  "schema_version": 7,
2241
- "version": "3.26.0",
2241
+ "version": "3.27.0",
2242
2242
  "elapsed_ms": 45,
2243
2243
  "total_issues": 12,
2244
2244
  "unused_files": [],
@@ -135,6 +135,16 @@ export type ElapsedMs = number
135
135
  * Value of `audit.gate`: which findings drive the `fallow audit` verdict.
136
136
  */
137
137
  export type AuditGate = ("new-only" | "all")
138
+ /**
139
+ * What a gate concluded on this run.
140
+ *
141
+ * Four-valued rather than a boolean because audit's verdict has a warn tier
142
+ * (`crates/cli/src/cli_report.rs` maps it onto three conclusions) and because
143
+ * a gate can stand down without passing. Widening a published boolean later
144
+ * would retype a required field and bump every carrying envelope, so the width
145
+ * is decided here.
146
+ */
147
+ export type GateStatus = ("pass" | "warn" | "fail" | "skipped")
138
148
  /**
139
149
  * Analysis mode stored with baselines, snapshots, audit sides, and impact data.
140
150
  */
@@ -402,6 +412,14 @@ export type DependencyOverrideSource = ("pnpm-workspace.yaml" | "package.json")
402
412
  * surfacing them statically catches the issue first.
403
413
  */
404
414
  export type DependencyOverrideMisconfigReason = ("unparsable-key" | "empty-value")
415
+ /**
416
+ * Which advisory a loaded baseline earned on this run.
417
+ *
418
+ * Mirrors `fallow_engine::baseline::BaselineStalenessWarning` so a consumer can
419
+ * render the same distinction the stderr warning makes, instead of inferring it
420
+ * from counts.
421
+ */
422
+ export type BaselineStalenessAdvisory = ("none" | "zero-overlap" | "partial")
405
423
  /**
406
424
  * Status of a regression-check pass.
407
425
  */
@@ -428,6 +446,25 @@ path: string
428
446
  * with a next-step hint.
429
447
  */
430
448
  message: string
449
+ /**
450
+ * True when this diagnostic reports a run whose RESULTS are degraded:
451
+ * something the user installed, wrote, or expected did not reach the
452
+ * analysis. Projected from [`WorkspaceDiagnosticKind::warns_on_stderr`],
453
+ * which is the same classification that decides whether the CLI prints a
454
+ * stderr line, so a CI log built from this field and a local non-quiet run
455
+ * say the same thing.
456
+ *
457
+ * Omitted when false, which is what keeps every clean run byte-identical.
458
+ * The two unconfigured-check kinds answer false on purpose: they fire in
459
+ * the product's default state on every project that never opted into
460
+ * boundaries or rule packs, so warning on them would warn forever. So does
461
+ * `excluded-by-default-ignore`, which is designed behavior on generated
462
+ * output; the alarm for that case is `no-source-files-analyzed`.
463
+ *
464
+ * Read this instead of hardcoding a kind allowlist: a degrading kind added
465
+ * in a later release then reaches an unchanged consumer.
466
+ */
467
+ degrades_analysis?: boolean
431
468
  } & WorkspaceDiagnostic1)
432
469
  export type WorkspaceDiagnostic1 = ({
433
470
  kind: "undeclared-workspace"
@@ -525,6 +562,14 @@ file_count: number
525
562
  */
526
563
  directory_count: number
527
564
  kind: "excluded-by-default-ignore"
565
+ } | {
566
+ /**
567
+ * Candidate source files the built-in ignore patterns removed from
568
+ * this walk, summed across every pattern. `0` when the walk found no
569
+ * candidate to exclude in the first place.
570
+ */
571
+ excluded_file_count: number
572
+ kind: "no-source-files-analyzed"
528
573
  })
529
574
  /**
530
575
  * Discriminant for [`CloneGroupAction::kind`]. Mirrors the action types
@@ -1311,6 +1356,16 @@ elapsed_ms: ElapsedMs
1311
1356
  base_snapshot_skipped?: (boolean | null)
1312
1357
  summary: AuditSummary
1313
1358
  attribution: AuditAttribution
1359
+ /**
1360
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
1361
+ * Each entry is the same rule that decides the exit code, so a CI
1362
+ * integration reads the verdict instead of guessing from a process status
1363
+ * it usually cannot see. A gate fails the build when `status` is `fail`
1364
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
1365
+ * rules fail a run with no flag at all, so an absent object means "no gate
1366
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
1367
+ */
1368
+ gate_outcomes?: (GateOutcomes | null)
1314
1369
  /**
1315
1370
  * `_meta` block with metric / rule definitions, when `--explain` was
1316
1371
  * passed.
@@ -1393,6 +1448,78 @@ styling_introduced: number
1393
1448
  styling_inherited: number
1394
1449
  duplication_demoted: number
1395
1450
  }
1451
+ /**
1452
+ * Every gate a run ARMED, keyed by name.
1453
+ *
1454
+ * Armed, not evaluated: a gate is armed by a flag or by config, never merely
1455
+ * because the rule behind it exists. Fallow's default severity rules fail a
1456
+ * run with no flag at all, so a `dead-code` run can exit 1 carrying no object
1457
+ * whatsoever. Read an absent object as "no gate was asked for", never as
1458
+ * "nothing failed".
1459
+ *
1460
+ * Absent from an envelope whenever it is empty, so a run that armed no gate is
1461
+ * byte-identical to one produced before this object existed. An empty object
1462
+ * is never emitted: it would assert that gates were armed and none tripped,
1463
+ * which is a different and false claim.
1464
+ *
1465
+ * The names this build can emit are `error-severity-findings`, `regression`,
1466
+ * `stale-baseline`, `duplication-threshold`, `health-min-score`,
1467
+ * `health-min-severity`, `health-findings`, `health-coverage-gaps`,
1468
+ * `health-runtime-coverage`, `security`, `security-advisory`, `audit-verdict`
1469
+ * and `type-aware-require`. The set is OPEN: a name a consumer does not
1470
+ * recognise means "some gate", not an error.
1471
+ */
1472
+ export interface GateOutcomes {
1473
+ [k: string]: GateOutcome
1474
+ }
1475
+ /**
1476
+ * One gate's verdict on one run.
1477
+ *
1478
+ * `status` and `enforced` answer different questions and legitimately
1479
+ * disagree. `status` is what the rule concluded; `enforced` is whether a
1480
+ * `fail` from this gate would make the run exit non-zero. A
1481
+ * `health --report-only` run is an explicit request never to fail, so a
1482
+ * failing gate there reports `status: fail` with `enforced: false`, and a
1483
+ * stale-baseline verdict published without `--fail-on-stale-baseline` reports
1484
+ * the same pair.
1485
+ *
1486
+ * **A gate fails the build when `status` is `fail` AND `enforced` is true.**
1487
+ * Neither member decides it alone: `enforced` is true on every armed gate,
1488
+ * including the ones that passed, so gating on it by itself fails every run
1489
+ * that armed anything. Read `status` on its own to decide what to say, and
1490
+ * remember that `warn` and `skipped` are neither a pass nor a failure.
1491
+ */
1492
+ export interface GateOutcome {
1493
+ status: GateStatus
1494
+ /**
1495
+ * True when a `fail` from this gate makes the run exit non-zero. False
1496
+ * when the verdict is published for information only, because the gate was
1497
+ * never armed or because the run was told never to fail.
1498
+ */
1499
+ enforced: boolean
1500
+ /**
1501
+ * The measured value the gate compared, when there is one: the duplication
1502
+ * percentage, the health score, or the number of findings at or above the
1503
+ * severity floor. Whole numbers are carried as JSON numbers, so a count of
1504
+ * three reads as `3.0`. Absent for gates that compare no number.
1505
+ */
1506
+ observed?: (number | null)
1507
+ /**
1508
+ * The configured limit `observed` was compared against, when there is one.
1509
+ * Absent for gates that compare no number.
1510
+ */
1511
+ threshold?: (number | null)
1512
+ /**
1513
+ * How the limit was spelled, for a gate whose `threshold` number does not
1514
+ * carry its own unit. `health-min-severity` sets it to the severity floor
1515
+ * (`moderate`, `high` or `critical`); `regression` sets it to the
1516
+ * tolerance as the user wrote it (`"50%"` or `"5"`), because `threshold`
1517
+ * there is the allowance in issues and the percentage would otherwise be
1518
+ * unrecoverable on the grouped envelope, which carries no `regression`
1519
+ * object. Absent for gates whose numbers speak for themselves.
1520
+ */
1521
+ threshold_label?: (string | null)
1522
+ }
1396
1523
  /**
1397
1524
  * Metric and rule definitions emitted under `_meta` when `--explain` is
1398
1525
  * passed (always present in MCP responses). Helps AI agents and CI systems
@@ -2670,10 +2797,29 @@ baseline_deltas?: (BaselineDeltas | null)
2670
2797
  * Which baseline snapshot was matched, in baseline runs.
2671
2798
  */
2672
2799
  baseline?: (BaselineMatch | null)
2800
+ /**
2801
+ * This run's view of the loaded baseline, present only in baseline runs.
2802
+ * Carries the staleness counts, the advisory verdict and `gate_trips`, the
2803
+ * same boolean `--fail-on-stale-baseline` exits on, so a CI integration
2804
+ * reads one field instead of restating the rule. Read `change_scoped`
2805
+ * before dividing `matched_entries` by `baseline_entries`: a narrowed run
2806
+ * can report `matched_entries: 0` on a healthy baseline.
2807
+ */
2808
+ baseline_staleness?: (BaselineStaleness | null)
2673
2809
  /**
2674
2810
  * Regression verdict against the baseline, in `--fail-on-regression` runs.
2675
2811
  */
2676
2812
  regression?: (RegressionResult | null)
2813
+ /**
2814
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
2815
+ * Each entry is the same rule that decides the exit code, so a CI
2816
+ * integration reads the verdict instead of guessing from a process status
2817
+ * it usually cannot see. A gate fails the build when `status` is `fail`
2818
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
2819
+ * rules fail a run with no flag at all, so an absent object means "no gate
2820
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
2821
+ */
2822
+ gate_outcomes?: (GateOutcomes | null)
2677
2823
  /**
2678
2824
  * `_meta` block with docs and rule definitions, when `--explain` was
2679
2825
  * passed.
@@ -5092,6 +5238,86 @@ entries: number
5092
5238
  */
5093
5239
  matched: number
5094
5240
  }
5241
+ /**
5242
+ * One run's machine-readable view of a loaded baseline.
5243
+ *
5244
+ * `stale` and `gate_trips` answer different questions and legitimately
5245
+ * disagree. `stale` mirrors the unasked-for stderr advisory, which stays silent
5246
+ * below a quarter of the baseline and on a run that produced no findings at
5247
+ * all, because a cleaned project and a rotted baseline look identical from
5248
+ * there. `gate_trips` mirrors the opt-in `--fail-on-stale-baseline` rule, which
5249
+ * a repository asks for precisely to catch those cases, so it fires on any
5250
+ * stale entry. A rotted baseline on a cleaned project reports
5251
+ * `stale: false` with `gate_trips: true`; that is the contract, not a defect.
5252
+ *
5253
+ * `change_scoped` is the member a consumer must read before dividing
5254
+ * `matched_entries` by `baseline_entries`. A run narrowed to part of the
5255
+ * project compares a whole-project baseline against a slice of it and can
5256
+ * report `matched_entries: 0` while the baseline is perfectly healthy, so both
5257
+ * `stale` and `gate_trips` are false there by construction. The remedy for a
5258
+ * tripped gate is always the same: re-save the baseline from a whole-project
5259
+ * run with `--save-baseline`.
5260
+ */
5261
+ export interface BaselineStaleness {
5262
+ /**
5263
+ * Entries carried by the loaded baseline file. On health these are the
5264
+ * complexity and CRAP finding entries; runtime-coverage suppressions and
5265
+ * refactoring target keys carried by the same file are not counted.
5266
+ */
5267
+ baseline_entries: number
5268
+ /**
5269
+ * Entries that matched a current finding on this run and were filtered out
5270
+ * of the report. On health this includes entries matched through a
5271
+ * followed file move.
5272
+ */
5273
+ matched_entries: number
5274
+ /**
5275
+ * Entries that matched no current finding on this run:
5276
+ * `baseline_entries - matched_entries`.
5277
+ */
5278
+ stale_entries: number
5279
+ /**
5280
+ * Findings this run produced before the baseline filtered them. Zero means
5281
+ * there was nothing to compare, either because the project is clean or
5282
+ * because the scope was empty, which is why `stale` stays false there even
5283
+ * when every entry went unmatched.
5284
+ */
5285
+ current_findings: number
5286
+ /**
5287
+ * True when this run analyzed only part of the project, so a whole-project
5288
+ * baseline matches less of it for reasons that are not rot. The channels
5289
+ * differ per command and include a diff, a base ref, `--changed-since`,
5290
+ * `--workspace`, `--changed-workspaces`, `--scope`, `--file`, an
5291
+ * issue-type filter, and production mode. Both `stale` and `gate_trips`
5292
+ * are false whenever this is true.
5293
+ */
5294
+ change_scoped: boolean
5295
+ /**
5296
+ * True exactly when the advisory stderr warning fired: not change-scoped,
5297
+ * at least one current finding before baseline filtering, and either
5298
+ * nothing matched or `stale_entries` reached a quarter of
5299
+ * `baseline_entries`.
5300
+ */
5301
+ stale: boolean
5302
+ warning: BaselineStalenessAdvisory
5303
+ /**
5304
+ * True exactly when
5305
+ * `!change_scoped && baseline_entries > 0 && matched_entries < baseline_entries`,
5306
+ * which is the rule `--fail-on-stale-baseline` applies. Deliberately
5307
+ * stricter than `stale`: any unmatched entry counts. It describes the
5308
+ * baseline, not the run's exit code: `health --report-only` is an explicit
5309
+ * request never to fail, so that run exits 0 and says so on stderr while
5310
+ * still reporting `gate_trips: true` here.
5311
+ */
5312
+ gate_trips: boolean
5313
+ /**
5314
+ * Entries that matched only by following a file move. Only `health` can
5315
+ * follow one, in its identity baseline mode; `dead-code` and `dupes` match
5316
+ * entries by fingerprint and never classify one as moved, so they report
5317
+ * `0`. Always `0` in health's count mode too.
5318
+ */
5319
+ moved_entries: number
5320
+ }
5095
5321
  /**
5096
5322
  * Result of regression detection (`--fail-on-regression`). Compares current
5097
5323
  * issue counts against a baseline from config or an explicit file.
@@ -6040,51 +6266,7 @@ severity_moderate_count: number
6040
6266
  /**
6041
6267
  * Baseline staleness data, present only when a baseline was loaded.
6042
6268
  */
6043
- baseline_staleness?: (HealthBaselineStaleness | null)
6044
- }
6045
- /**
6046
- * Staleness of a loaded health baseline.
6047
- *
6048
- * Reports how many saved complexity and CRAP finding entries still matched a
6049
- * current finding on this run, so consumers can see a rotting baseline before
6050
- * it degrades to zero overlap. Runtime-coverage suppressions and refactoring
6051
- * target keys carried by the same baseline are not counted here. Present in
6052
- * the summary only when a baseline was loaded.
6053
- */
6054
- export interface HealthBaselineStaleness {
6055
- /**
6056
- * Complexity and CRAP finding entries carried by the loaded baseline.
6057
- */
6058
- baseline_entries: number
6059
- /**
6060
- * Entries that matched a current finding in the active baseline mode,
6061
- * including entries matched through a followed file move.
6062
- */
6063
- matched_entries: number
6064
- /**
6065
- * Entries that matched no current finding on this run.
6066
- */
6067
- stale_entries: number
6068
- /**
6069
- * Entries that matched only by following a file move in identity mode.
6070
- * Always zero in count mode.
6071
- */
6072
- moved_entries: number
6073
- /**
6074
- * True when this run analyzed a subset of the project (changed-file,
6075
- * diff, or workspace scoping, or production mode, which drops test, story
6076
- * and dev files), so the baseline was compared against a narrowed finding
6077
- * set and staleness cannot be judged. `stale` is always false on scoped
6078
- * runs.
6079
- */
6080
- change_scoped: boolean
6081
- /**
6082
- * True exactly when the run was not change-scoped, at least one current
6083
- * finding existed before baseline filtering, and `stale_entries` reached
6084
- * a quarter of `baseline_entries`. Mirrors the human warning so machine
6085
- * consumers do not have to reimplement the threshold.
6086
- */
6087
- stale: boolean
6269
+ baseline_staleness?: (BaselineStaleness | null)
6088
6270
  }
6089
6271
  /**
6090
6272
  * Report entry describing whether a threshold override is active, stale, or
@@ -10835,6 +11017,16 @@ grouped_by?: (GroupByMode | null)
10835
11017
  * Per-bucket recomputed metrics; present only in grouped output.
10836
11018
  */
10837
11019
  groups?: (HealthGroup[] | null)
11020
+ /**
11021
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
11022
+ * Each entry is the same rule that decides the exit code, so a CI
11023
+ * integration reads the verdict instead of guessing from a process status
11024
+ * it usually cannot see. A gate fails the build when `status` is `fail`
11025
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
11026
+ * rules fail a run with no flag at all, so an absent object means "no gate
11027
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
11028
+ */
11029
+ gate_outcomes?: (GateOutcomes | null)
10838
11030
  /**
10839
11031
  * `_meta` block with metric definitions, when `--explain` was passed.
10840
11032
  */
@@ -11009,6 +11201,25 @@ total_issues?: (number | null)
11009
11201
  * Grouped findings; present only in grouped output.
11010
11202
  */
11011
11203
  groups?: (DuplicationGroup[] | null)
11204
+ /**
11205
+ * This run's view of the loaded baseline, present only in baseline runs.
11206
+ * Carries the staleness counts, the advisory verdict and `gate_trips`, the
11207
+ * same boolean `--fail-on-stale-baseline` exits on, so a CI integration
11208
+ * reads one field instead of restating the rule. Read `change_scoped`
11209
+ * before dividing `matched_entries` by `baseline_entries`: a narrowed run
11210
+ * can report `matched_entries: 0` on a healthy baseline.
11211
+ */
11212
+ baseline_staleness?: (BaselineStaleness | null)
11213
+ /**
11214
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
11215
+ * Each entry is the same rule that decides the exit code, so a CI
11216
+ * integration reads the verdict instead of guessing from a process status
11217
+ * it usually cannot see. A gate fails the build when `status` is `fail`
11218
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
11219
+ * rules fail a run with no flag at all, so an absent object means "no gate
11220
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
11221
+ */
11222
+ gate_outcomes?: (GateOutcomes | null)
11012
11223
  /**
11013
11224
  * `_meta` block with metric / rule definitions, emitted when `--explain`
11014
11225
  * is passed (always present in MCP responses).
@@ -11167,6 +11378,25 @@ total_issues: number
11167
11378
  * One bucket per resolver key.
11168
11379
  */
11169
11380
  groups: CheckGroupedEntry[]
11381
+ /**
11382
+ * This run's view of the loaded baseline, present only in baseline runs.
11383
+ * Carries the staleness counts, the advisory verdict and `gate_trips`, the
11384
+ * same boolean `--fail-on-stale-baseline` exits on, so a CI integration
11385
+ * reads one field instead of restating the rule. Read `change_scoped`
11386
+ * before dividing `matched_entries` by `baseline_entries`: a narrowed run
11387
+ * can report `matched_entries: 0` on a healthy baseline.
11388
+ */
11389
+ baseline_staleness?: (BaselineStaleness | null)
11390
+ /**
11391
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
11392
+ * Each entry is the same rule that decides the exit code, so a CI
11393
+ * integration reads the verdict instead of guessing from a process status
11394
+ * it usually cannot see. A gate fails the build when `status` is `fail`
11395
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
11396
+ * rules fail a run with no flag at all, so an absent object means "no gate
11397
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
11398
+ */
11399
+ gate_outcomes?: (GateOutcomes | null)
11170
11400
  /**
11171
11401
  * `_meta` block with docs and rule definitions, when `--explain` was
11172
11402
  * passed.
@@ -11836,6 +12066,16 @@ schema_version: SecuritySchemaVersion
11836
12066
  version: ToolVersion
11837
12067
  elapsed_ms: ElapsedMs
11838
12068
  config: SecurityOutputConfig
12069
+ /**
12070
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
12071
+ * Each entry is the same rule that decides the exit code, so a CI
12072
+ * integration reads the verdict instead of guessing from a process status
12073
+ * it usually cannot see. A gate fails the build when `status` is `fail`
12074
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
12075
+ * rules fail a run with no flag at all, so an absent object means "no gate
12076
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
12077
+ */
12078
+ gate_outcomes?: (GateOutcomes | null)
11839
12079
  /**
11840
12080
  * Security-specific rule and field metadata, emitted with `--explain`.
11841
12081
  */
@@ -12459,6 +12699,16 @@ schema_version: SecuritySchemaVersion
12459
12699
  version: ToolVersion
12460
12700
  elapsed_ms: ElapsedMs
12461
12701
  config: SecurityOutputConfig
12702
+ /**
12703
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
12704
+ * Each entry is the same rule that decides the exit code, so a CI
12705
+ * integration reads the verdict instead of guessing from a process status
12706
+ * it usually cannot see. A gate fails the build when `status` is `fail`
12707
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
12708
+ * rules fail a run with no flag at all, so an absent object means "no gate
12709
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
12710
+ */
12711
+ gate_outcomes?: (GateOutcomes | null)
12462
12712
  /**
12463
12713
  * Security-specific rule and field metadata, emitted with `--explain`.
12464
12714
  */
@@ -12742,6 +12992,16 @@ export interface CombinedOutput {
12742
12992
  schema_version: CombinedSchemaVersion
12743
12993
  version: ToolVersion
12744
12994
  elapsed_ms: ElapsedMs
12995
+ /**
12996
+ * Every gate this run ARMED, keyed by name, absent when it armed none.
12997
+ * Each entry is the same rule that decides the exit code, so a CI
12998
+ * integration reads the verdict instead of guessing from a process status
12999
+ * it usually cannot see. A gate fails the build when `status` is `fail`
13000
+ * AND `enforced` is true. Armed, not evaluated: fallow's default severity
13001
+ * rules fail a run with no flag at all, so an absent object means "no gate
13002
+ * was asked for", never "nothing failed". See [`crate::GateOutcomes`].
13003
+ */
13004
+ gate_outcomes?: (GateOutcomes | null)
12745
13005
  /**
12746
13006
  * Per-section `_meta` blocks, when `--explain` was passed.
12747
13007
  */
@@ -15283,3 +15543,8 @@ export type UnusedDependency = UnusedDependencyFinding | UnusedDevDependencyFind
15283
15543
  * this alias; new code should narrow on the specific wrapper variant.
15284
15544
  */
15285
15545
  export type UnusedMember = UnusedClassMemberFinding | UnusedEnumMemberFinding | UnusedStoreMemberFinding;
15546
+
15547
+ /**
15548
+ * @deprecated Renamed to BaselineStaleness in 3.27.0, when dead-code and dupes started carrying the same shape. The members are unchanged.
15549
+ */
15550
+ export type HealthBaselineStaleness = BaselineStaleness;