fallow 2.94.0 → 2.96.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fallow",
3
- "version": "2.94.0",
3
+ "version": "2.96.0",
4
4
  "description": "Deterministic codebase intelligence for TypeScript and JavaScript. Quality, risk, architecture, dependencies, duplication, and safe cleanup evidence for humans, CI, and agents. Optional runtime intelligence layer (Fallow Runtime) adds production execution evidence. Rust-native, sub-second, zero-config framework support.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -83,13 +83,13 @@
83
83
  "@tanstack/intent": "0.0.41"
84
84
  },
85
85
  "optionalDependencies": {
86
- "@fallow-cli/darwin-arm64": "2.94.0",
87
- "@fallow-cli/darwin-x64": "2.94.0",
88
- "@fallow-cli/linux-x64-gnu": "2.94.0",
89
- "@fallow-cli/linux-arm64-gnu": "2.94.0",
90
- "@fallow-cli/linux-x64-musl": "2.94.0",
91
- "@fallow-cli/linux-arm64-musl": "2.94.0",
92
- "@fallow-cli/win32-arm64-msvc": "2.94.0",
93
- "@fallow-cli/win32-x64-msvc": "2.94.0"
86
+ "@fallow-cli/darwin-arm64": "2.96.0",
87
+ "@fallow-cli/darwin-x64": "2.96.0",
88
+ "@fallow-cli/linux-x64-gnu": "2.96.0",
89
+ "@fallow-cli/linux-arm64-gnu": "2.96.0",
90
+ "@fallow-cli/linux-x64-musl": "2.96.0",
91
+ "@fallow-cli/linux-arm64-musl": "2.96.0",
92
+ "@fallow-cli/win32-arm64-msvc": "2.96.0",
93
+ "@fallow-cli/win32-x64-msvc": "2.96.0"
94
94
  }
95
95
  }
package/schema.json CHANGED
@@ -112,7 +112,7 @@
112
112
  "ignoreDefaults": true,
113
113
  "skipLocal": false,
114
114
  "crossLanguage": false,
115
- "ignoreImports": false,
115
+ "ignoreImports": true,
116
116
  "normalization": {},
117
117
  "minCorpusSizeForShingleFilter": 1024,
118
118
  "minCorpusSizeForTokenCache": 5000
@@ -697,9 +697,9 @@
697
697
  "default": false
698
698
  },
699
699
  "ignoreImports": {
700
- "description": "Exclude ES `import` declarations from clone detection.\n\nWhen enabled, all `import` statements (value imports, type imports, and\nside-effect imports) are stripped from the token stream before clone\ndetection. This reduces noise from sorted import blocks that naturally\nlook similar across files. Only affects ES `import` declarations;\nCommonJS `require()` calls are not filtered.",
700
+ "description": "Exclude ES `import` declarations from clone detection.\n\nDefaults to `true`: token-identical sorted import blocks are a structural\nproperty of well-formatted code, not copy-paste, so they should not\nsurface as clone groups. Set to `false` to count import blocks again.\nWhen enabled, all `import` statements (value imports, type imports, and\nside-effect imports) are stripped from the token stream before clone\ndetection. Only affects ES `import` declarations; CommonJS `require()`\ncalls and `export ... from` re-export blocks are still counted.",
701
701
  "type": "boolean",
702
- "default": false
702
+ "default": true
703
703
  },
704
704
  "normalization": {
705
705
  "description": "Fine-grained normalization overrides on top of the detection mode.",
@@ -832,6 +832,13 @@
832
832
  },
833
833
  "default": []
834
834
  },
835
+ "thresholdOverrides": {
836
+ "description": "Per-file or per-function threshold overrides. These keep exceptional\nfunctions visible as configured numeric ceilings instead of hiding them\nbehind binary suppressions.",
837
+ "type": "array",
838
+ "items": {
839
+ "$ref": "#/$defs/HealthThresholdOverride"
840
+ }
841
+ },
835
842
  "ownership": {
836
843
  "description": "Ownership analysis configuration. Controls bot filtering and email\nprivacy mode for `--ownership` output.",
837
844
  "$ref": "#/$defs/OwnershipConfig",
@@ -852,7 +859,67 @@
852
859
  "type": "boolean",
853
860
  "default": true
854
861
  }
855
- }
862
+ },
863
+ "additionalProperties": false
864
+ },
865
+ "HealthThresholdOverride": {
866
+ "description": "Per-file or per-function health threshold override.",
867
+ "type": "object",
868
+ "properties": {
869
+ "files": {
870
+ "description": "Project-root-relative file globs this override applies to.",
871
+ "type": "array",
872
+ "items": {
873
+ "type": "string"
874
+ }
875
+ },
876
+ "functions": {
877
+ "description": "Exact emitted function names this override applies to. Empty means every\nfunction in matching files.",
878
+ "type": "array",
879
+ "items": {
880
+ "type": "string"
881
+ }
882
+ },
883
+ "maxCyclomatic": {
884
+ "description": "Local cyclomatic complexity ceiling.",
885
+ "type": [
886
+ "integer",
887
+ "null"
888
+ ],
889
+ "format": "uint16",
890
+ "minimum": 0,
891
+ "maximum": 65535
892
+ },
893
+ "maxCognitive": {
894
+ "description": "Local cognitive complexity ceiling.",
895
+ "type": [
896
+ "integer",
897
+ "null"
898
+ ],
899
+ "format": "uint16",
900
+ "minimum": 0,
901
+ "maximum": 65535
902
+ },
903
+ "maxCrap": {
904
+ "description": "Local CRAP ceiling.",
905
+ "type": [
906
+ "number",
907
+ "null"
908
+ ],
909
+ "format": "double"
910
+ },
911
+ "reason": {
912
+ "description": "Human-readable rationale for the exception.",
913
+ "type": [
914
+ "string",
915
+ "null"
916
+ ]
917
+ }
918
+ },
919
+ "additionalProperties": false,
920
+ "required": [
921
+ "files"
922
+ ]
856
923
  },
857
924
  "OwnershipConfig": {
858
925
  "description": "Configuration for ownership analysis (`fallow health --hotspots --ownership`).",
@@ -106,7 +106,7 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
106
106
  | `config` | Show the loaded config path and resolved config (verifies which `.fallowrc.json` is in effect) | `--path` |
107
107
  | `list` | Inspect project structure | `--files`, `--entry-points`, `--plugins`, `--boundaries`, `--workspaces` |
108
108
  | `workspaces` | Inspect monorepo workspaces + discovery diagnostics (shorthand for `list --workspaces`) | (no flags) |
109
- | `dupes` | Code duplication detection | `--mode`, `--threshold`, `--top`, `--changed-since`, `--workspace`, `--changed-workspaces`, `--skip-local`, `--cross-language`, `--ignore-imports`, `--explain-skipped`, `--fail-on-regression`, `--tolerance`, `--regression-baseline`, `--save-regression-baseline` |
109
+ | `dupes` | Code duplication detection | `--mode`, `--threshold`, `--top`, `--changed-since`, `--workspace`, `--changed-workspaces`, `--skip-local`, `--cross-language`, `--ignore-imports`, `--no-ignore-imports`, `--explain-skipped`, `--fail-on-regression`, `--tolerance`, `--regression-baseline`, `--save-regression-baseline` |
110
110
  | `health` | Function complexity analysis (also covers Angular templates as synthetic `<template>` findings: external `.html` files via `templateUrl` AND inline `@Component({ template: \`...\` })` literals; suppress external with `<!-- fallow-ignore-file complexity -->` at the top of the `.html` file, suppress inline with `// fallow-ignore-next-line complexity` directly above the `@Component` decorator) | `--complexity`, `--max-cyclomatic`, `--max-cognitive`, `--max-crap`, `--top`, `--sort`, `--file-scores`, `--hotspots`, `--ownership`, `--ownership-emails`, `--targets`, `--effort`, `--score`, `--min-score`, `--since`, `--min-commits`, `--save-snapshot`, `--trend`, `--coverage-gaps`, `--coverage`, `--coverage-root`, `--runtime-coverage`, `--min-invocations-hot`, `--min-observation-volume`, `--low-traffic-threshold`, `--workspace`, `--changed-workspaces`, `--baseline`, `--save-baseline` |
111
111
  | `flags` | Detect feature flag patterns (env vars, SDK calls, config objects) | `--top` |
112
112
  | `explain` | Explain one issue type without running analysis | `<issue-type>`, `--format json` |
@@ -149,7 +149,7 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
149
149
  | `boundary-violation` | `--boundary-violations` | - | `// fallow-ignore-next-line boundary-violation` | Imports crossing architecture zone boundaries. Presets: `layered`, `hexagonal`, `feature-sliced`, `bulletproof`; `autoDiscover` can create one zone per feature directory; per-rule `allowTypeOnly: [zones]` admits `import type` / `export type` crossings while still blocking value imports. Optional sections: `boundaries.coverage.requireAllFiles` reports unzoned source files (`allowUnmatched` globs exempt intentional ones), and `boundaries.calls.forbidden` bans callee patterns per zone (segment-aware and import-resolved, so `child_process.*` covers `node:child_process` named/namespace/default imports; direct callees only, zoned files only). The whole family shares the `boundary-violation` rule and suppression token (`boundary-call-violation` and `boundary-call-violations` accepted as aliases); start the rule at `warn` for a staged rollout |
150
150
  | `boundary-coverage` | - | - | `// fallow-ignore-file boundary-violation` | Source file matches no configured architecture boundary zone; Requires boundaries.coverage.requireAllFiles |
151
151
  | `boundary-call-violation` | - | - | `// fallow-ignore-next-line boundary-call-violation` | Zoned file calls a callee its zone forbids; Requires boundaries.calls.forbidden patterns |
152
- | `policy-violation` | `--policy-violations` | - | `// fallow-ignore-next-line policy-violation` | Calls or imports banned by a declarative rule pack (`rulePacks` config key lists standalone JSON/JSONC files of `banned-call` / `banned-import` rules; pure data, no project code executes). Findings identified as `<pack>/<rule-id>`. Default `warn` master; per-rule `severity` overrides per finding and the exit gate reads the effective severity. Invalid or missing packs fail config load with exit 2. `fallow rule-pack-schema` prints the pack JSON Schema. Suppress with `// fallow-ignore-next-line policy-violation` (one token covers every pack rule on the line). |
152
+ | `policy-violation` | `--policy-violations` | - | `// fallow-ignore-next-line policy-violation` | Calls or imports banned by a declarative rule pack (`rulePacks` config key lists standalone JSON/JSONC files of `banned-call` / `banned-import` rules; pure data, no project code executes). Findings identified as `<pack>/<rule-id>`. Default `warn` master; per-rule `severity` overrides per finding and the exit gate reads the effective severity. Invalid or missing packs fail config load with exit 2. `fallow rule-pack-schema` prints the pack JSON Schema. Use the scoped token to suppress one rule; bare `policy-violation` still covers every pack rule on the line or file. |
153
153
  | `stale-suppression` | `--stale-suppressions` | - | - | `fallow-ignore` comments or `@expected-unused` JSDoc tags that no longer match any issue |
154
154
  | `unused-catalog-entry` | `--unused-catalog-entries` | yes | - | `pnpm-workspace.yaml` entries no workspace package.json references via `catalog:` (default `warn`) |
155
155
  | `empty-catalog-group` | `--empty-catalog-groups` | - | - | Named `catalogs.<name>:` groups in `pnpm-workspace.yaml` with no entries. Top-level `catalog:` placeholders are ignored. Default `warn`. |
@@ -198,7 +198,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
198
198
  | `project_info` | introspection | free | `entry_points`, `files`, `plugins`, `boundaries` | Project metadata. Set `entry_points`, `files`, `plugins`, or `boundaries` to `true` to request specific sections |
199
199
  | `list_boundaries` | introspection | free | - | Architecture boundary zones, access rules, and pre-expansion `autoDiscover` `logical_groups[]` (user-authored parent name, verbatim paths, discovered children, `status` enum, summed `file_count`). Returns `{"configured": false}` if no boundaries configured |
200
200
  | `feature_flags` | analysis | free | `workspace`, `production` | Detect feature flag patterns (env vars, SDK calls, config objects). Set `top` to limit results |
201
- | `impact` | introspection | free | `root` | Read the local, opt-in Fallow Impact value report (`fallow impact --format json`). Runs no analysis: current surfacing counts, trend since the last recorded run, pre-commit gate containment, and (on impact v1.5+) resolved/suppressed attribution. Read-only and `root`-only; the mutating `enable` / `disable` lifecycle is not exposed. A never-enabled project returns a populated `{"enabled": false, ...}` report (never `{}`); branch on `enabled` then `record_count` and recommend the user run `fallow impact enable` rather than toggling it. Local-developer signal: empty in ephemeral CI runners, so not a CI metric |
201
+ | `impact` | introspection | free | `root` | Read the local, opt-in Fallow Impact value report (`fallow impact --format json`). Runs no analysis: current surfacing counts, trend since the last recorded run, pre-commit gate containment, and (on impact v1.5+) resolved/suppressed attribution. History is read from a per-project file in the user's private config dir (never inside the repo). Read-only and `root`-only; the mutating `enable` / `disable` / `default` lifecycle is not exposed. A never-enabled project returns a populated `{"enabled": false, ...}` report (never `{}`); branch on `enabled` and `enabled_source` (`project` / `user` / `default`) then `record_count`, recommending `fallow impact enable` only when `explicit_decision` is `false` (never asked) and staying silent when `true` (deliberately disabled here). Local-developer signal: fallow never records in CI, so empty there and not a CI metric |
202
202
  | `trace_export` | trace | free | `file`, `export_name` | Trace why an export is used or unused (`fallow dead-code --trace FILE:EXPORT_NAME --format json`). Required `file` and `export_name`. Returns file reachability, entry-point status, direct references, re-export chains, and a reason string. Use before deleting a supposedly-unused export |
203
203
  | `trace_file` | trace | free | `file` | Trace all graph edges for a file (`fallow dead-code --trace-file PATH --format json`). Required `file`. Returns reachability, exports, imports-from, imported-by, and re-exports. Use to decide whether a file is isolated, barrel-only, or imported by live entry points |
204
204
  | `trace_dependency` | trace | free | `package_name` | Trace where a dependency is imported (`fallow dead-code --trace-dependency PACKAGE --format json`). Required `package_name`. Returns importing files, type-only importers, total import count, `used_in_scripts` (true when invoked from package.json scripts or CI configs), and `is_used` (combined import + script signal; mirrors the unused-deps detector so build tools like `microbundle` or `vitest` are not falsely flagged as unused). Use before removing a dependency or moving between `dependencies` and `devDependencies` |
@@ -218,14 +218,14 @@ Most tools accept `root`, `config`, `no_cache`, and `threads` params. Exceptions
218
218
 
219
219
  All JSON responses include structured `actions` arrays on every finding (dead code, health, duplication), enabling programmatic fix application or suppression.
220
220
 
221
+ `health.thresholdOverrides[]` lets projects keep known legacy functions visible as configured local ceilings instead of hiding them with suppressions. Each entry has `files` globs, optional exact `functions`, one or more of `maxCyclomatic`, `maxCognitive`, or `maxCrap`, and optional `reason`. Health JSON may include top-level `threshold_overrides[]` entries with `active`, `stale`, or `no_match` status, and complexity findings that use an override carry `effective_thresholds` plus `threshold_source: "override"`.
222
+
221
223
  `dead-code`, `health`, `dupes`, bare `fallow`, and `audit` JSON output also carry a top-level `next_steps` array of read-only follow-up commands computed from the run's findings: each entry is `{ id, command, reason }`. The `command` is runnable as-is (never a placeholder, never `fix` or any other mutating command); the stable kebab-case `id` (`setup`, `impact-report`, `trace-unused-export`, `trace-clone`, `complexity-breakdown`, `scope-workspaces`, `audit-changed`) maps to a verification step you should run BEFORE acting, for example tracing an export before deleting it. A leading `setup` step (command: `fallow schema`) appears only on unconfigured, non-CI projects with findings and doubles as the onboarding trigger below; it disappears after setup or `fallow init --decline`. An at-most-weekly `impact-report` step (command: `fallow impact`) carries the local value digest when impact tracking has non-zero results; it may ride a clean run. When running via MCP, dispatch on the `id` to the matching tool / `code_execute` host call (`trace_export`, `trace_clone`, `check_health` with `complexity_breakdown: true`, `audit`) rather than shelling out the CLI string. The array is deduplicated, capped at three, and omitted when empty; set `FALLOW_SUGGESTIONS=off` to suppress it.
222
224
 
223
225
  ## Node.js Bindings
224
-
225
226
  Embedding fallow in a Node.js process (editor extensions, servers, custom tooling)? Use the `@fallow-cli/fallow-node` NAPI bindings instead of spawning the CLI: six async functions (`detectDeadCode`, `detectCircularDependencies`, `detectBoundaryViolations`, `detectDuplication`, `computeComplexity`, `computeHealth`) returning the same JSON envelopes as `--format json`. Read-only analysis only; use the CLI for write-path commands. Details: [Node Bindings](references/node-bindings.md).
226
227
 
227
228
  ## References
228
-
229
229
  - [CLI Reference](references/cli-reference.md): complete command and flag specifications, plus configuration field details
230
230
  - [Gotchas](references/gotchas.md): common pitfalls, edge cases, and correct usage patterns
231
231
  - [Patterns](references/patterns.md): workflow recipes for CI, monorepos, migration, and incremental adoption
@@ -400,7 +400,7 @@ fallow impact enable
400
400
  fallow impact --format json --quiet
401
401
  ```
402
402
 
403
- `fallow impact enable` is a one-time, user-owned local action; the agent-facing line is the read step. The store lives at `.fallow/impact.json` (gitignored), the report is read-only, and it is empty in ephemeral CI runners.
403
+ `fallow impact enable` is a one-time, user-owned local action; the agent-facing line is the read step. History is stored per-project in the user's private config dir (never inside the repo, so no `.fallow/` or `.gitignore` changes); `fallow impact default on` enables it for every project at once. The report is read-only and is empty in CI (fallow never records there).
404
404
 
405
405
  ### Debug why something is flagged
406
406
 
@@ -147,6 +147,7 @@ By default, `fallow dupes` skips generated framework output matching `**/.next/*
147
147
  | `--skip-local` | `bool` | `false` | Only report cross-directory duplicates |
148
148
  | `--cross-language` | `bool` | `false` | Strip type annotations for TS↔JS matching |
149
149
  | `--ignore-imports` | `bool` | `false` | Exclude import declarations from clone detection |
150
+ | `--no-ignore-imports` | `bool` | `false` | Count import declarations as clone candidates (opt out of the default import exclusion) |
150
151
  | `--top` | `string` | - | Show only the N most-duplicated clone groups (sorted by instance count desc, tiebreak: line count desc, then path/line). Summary stats reflect the full project. |
151
152
  | `--trace` | `string` | - | Deep-dive clones. `FILE:LINE` traces all clones at a location; `dup:<id>` traces a clone group by the stable fingerprint shown in the listing and on `clone_groups[].fingerprint` in JSON. Fingerprints are usually `dup:<8hex>` and widen only on rare report collisions. Trace output adds an extract-function suggestion, estimated savings, and a best-effort proposed name per group |
152
153
 
@@ -492,7 +493,7 @@ fallow health --format json --quiet --trend
492
493
  {
493
494
  "kind": "health",
494
495
  "schema_version": 7,
495
- "version": "2.94.0",
496
+ "version": "2.96.0",
496
497
  "elapsed_ms": 32,
497
498
  "summary": {
498
499
  "files_analyzed": 482,
@@ -516,6 +517,8 @@ fallow health --format json --quiet --trend
516
517
  }
517
518
  ```
518
519
 
520
+ `health.thresholdOverrides[]` config entries can raise local cyclomatic, cognitive, or CRAP ceilings for matching files and optional exact function names. When an override affects output, health JSON includes top-level `threshold_overrides[]` state entries (`active`, `stale`, or `no_match`). Complexity findings evaluated with local ceilings include `effective_thresholds` and `threshold_source: "override"` so agents can see which thresholds drove the finding and avoid treating configured exceptions as hidden suppressions.
521
+
519
522
  When the unit size very-high-risk percentage is >= 3%, the JSON output includes a `large_functions` array listing functions exceeding 60 lines of code:
520
523
 
521
524
  ```json
@@ -877,7 +880,7 @@ fallow audit \
877
880
  {
878
881
  "kind": "audit",
879
882
  "schema_version": 7,
880
- "version": "2.94.0",
883
+ "version": "2.96.0",
881
884
  "command": "audit",
882
885
  "verdict": "fail",
883
886
  "changed_files_count": 12,
@@ -952,7 +955,7 @@ fallow flags --format json --quiet --workspace my-package
952
955
  ```json
953
956
  {
954
957
  "schema_version": 7,
955
- "version": "2.94.0",
958
+ "version": "2.96.0",
956
959
  "elapsed_ms": 116,
957
960
  "feature_flags": [],
958
961
  "total_flags": 0
@@ -1052,7 +1055,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1052
1055
  {
1053
1056
  "kind": "security",
1054
1057
  "schema_version": "4",
1055
- "version": "2.94.0",
1058
+ "version": "2.96.0",
1056
1059
  "elapsed_ms": 42,
1057
1060
  "config": {
1058
1061
  "rules": {
@@ -1081,7 +1084,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1081
1084
  {
1082
1085
  "kind": "security",
1083
1086
  "schema_version": "4",
1084
- "version": "2.94.0",
1087
+ "version": "2.96.0",
1085
1088
  "elapsed_ms": 42,
1086
1089
  "config": {
1087
1090
  "rules": {
@@ -1543,6 +1546,7 @@ Available on all commands:
1543
1546
  | `--dupes-skip-local` | `bool` | `false` | Only report cross-directory duplicates in combined mode |
1544
1547
  | `--dupes-cross-language` | `bool` | `false` | Enable cross-language duplicate detection in combined mode |
1545
1548
  | `--dupes-ignore-imports` | `bool` | `false` | Exclude import declarations from duplicate detection in combined mode |
1549
+ | `--dupes-no-ignore-imports` | `bool` | `false` | Count import declarations as clone candidates in combined mode (opt out of the default import exclusion) |
1546
1550
  | `--score` | `bool` | `false` | Compute health score (0-100 with letter grade) in combined mode. Enables the health delta header in PR comments. JSON includes `health_score` object with `score`, `grade`, and `penalties` breakdown |
1547
1551
  | `--trend` | `bool` | `false` | Compare current health metrics against saved snapshot. Implies `--score`. Shows per-metric deltas with directional indicators. Requires at least one saved snapshot in `.fallow/snapshots/` |
1548
1552
  | `--save-snapshot` | `string` | - | Save vital signs snapshot for trend tracking. Default path: `.fallow/snapshots/<timestamp>.json`. Forces file-scores + hotspot computation |
@@ -1697,7 +1701,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
1697
1701
  {
1698
1702
  "kind": "dead-code",
1699
1703
  "schema_version": 7,
1700
- "version": "2.94.0",
1704
+ "version": "2.96.0",
1701
1705
  "elapsed_ms": 45,
1702
1706
  "total_issues": 12,
1703
1707
  "entry_points": {
@@ -1857,7 +1861,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
1857
1861
  {
1858
1862
  "kind": "dupes",
1859
1863
  "schema_version": 7,
1860
- "version": "2.94.0",
1864
+ "version": "2.96.0",
1861
1865
  "elapsed_ms": 82,
1862
1866
  "total_clones": 15,
1863
1867
  "total_lines_duplicated": 230,
@@ -1901,11 +1905,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
1901
1905
  {
1902
1906
  "kind": "combined",
1903
1907
  "schema_version": 7,
1904
- "version": "2.94.0",
1908
+ "version": "2.96.0",
1905
1909
  "elapsed_ms": 159,
1906
1910
  "check": {
1907
1911
  "schema_version": 7,
1908
- "version": "2.94.0",
1912
+ "version": "2.96.0",
1909
1913
  "elapsed_ms": 45,
1910
1914
  "total_issues": 12,
1911
1915
  "unused_files": [],
@@ -390,6 +390,10 @@ export type ComplexityMetric = ("cyclomatic" | "cognitive")
390
390
  * to cyclomatic complexity and so produces no contribution.
391
391
  */
392
392
  export type ComplexityContributionKind = ("if" | "else" | "else-if" | "ternary" | "logical-and" | "logical-or" | "nullish-coalescing" | "logical-assignment" | "optional-chain" | "for" | "for-in" | "for-of" | "while" | "do-while" | "switch" | "case" | "catch" | "labeled-break" | "labeled-continue")
393
+ /**
394
+ * Source for a finding's effective thresholds.
395
+ */
396
+ export type ThresholdSource = "override"
393
397
  /**
394
398
  * Discriminant for [`HealthFindingAction::kind`]. Mirrors the action types
395
399
  * emitted by `build_health_finding_actions`. A single finding's `actions`
@@ -407,6 +411,10 @@ export type CoverageModel = ("static_binary" | "static_estimated" | "istanbul")
407
411
  * Whether CRAP findings in the report used one coverage-source kind or a mix.
408
412
  */
409
413
  export type CoverageSourceConsistency = ("uniform" | "mixed")
414
+ /**
415
+ * Lifecycle state for a configured threshold override.
416
+ */
417
+ export type ThresholdOverrideStatus = ("active" | "stale" | "no_match")
410
418
  /**
411
419
  * Discriminant for [`UntestedFileAction::kind`]. Mirrors the action types
412
420
  * emitted by `build_untested_file_actions`.
@@ -615,6 +623,12 @@ export type GroupByMode = ("owner" | "directory" | "package" | "section")
615
623
  * `CoverageAnalyzeSchemaVersion`).
616
624
  */
617
625
  export type ImpactReportSchemaVersion = "1"
626
+ /**
627
+ * Why Impact tracking is (or is not) active for a project. `Project` = an
628
+ * explicit per-repo `enable`; `User` = the user-global default with no per-repo
629
+ * decision; `Default` = off (no per-repo decision and no global default).
630
+ */
631
+ export type EnabledSource = ("project" | "user" | "default")
618
632
  /**
619
633
  * Direction of a count trend between two recorded runs.
620
634
  */
@@ -2080,8 +2094,8 @@ introduced?: (AuditIntroduced | null)
2080
2094
  }
2081
2095
  /**
2082
2096
  * Wire-shape envelope for a [`PolicyViolation`] finding. Carries actions for
2083
- * replacing the banned call or import, or suppressing it with the
2084
- * `policy-violation` token.
2097
+ * replacing the banned call or import, or suppressing it with a scoped
2098
+ * `policy-violation:<pack>/<rule-id>` token.
2085
2099
  */
2086
2100
  export interface PolicyViolationFinding {
2087
2101
  /**
@@ -2816,6 +2830,11 @@ export interface HealthReport {
2816
2830
  */
2817
2831
  findings: HealthFinding[]
2818
2832
  summary: HealthSummary
2833
+ /**
2834
+ * Configured threshold override states. Entries are emitted for active
2835
+ * exceptions, stale exceptions, and full-run no-match cleanup hints.
2836
+ */
2837
+ threshold_overrides?: ThresholdOverrideState[]
2819
2838
  /**
2820
2839
  * Project-wide vital signs (always computed from available data).
2821
2840
  */
@@ -2915,6 +2934,15 @@ component_rollup?: (ComponentRollup | null)
2915
2934
  * otherwise so default and CI output stay lean.
2916
2935
  */
2917
2936
  contributions?: ComplexityContribution[]
2937
+ /**
2938
+ * Resolved thresholds used for this finding when a config override changed
2939
+ * at least one ceiling. Omitted for findings using global thresholds.
2940
+ */
2941
+ effective_thresholds?: (HealthEffectiveThresholds | null)
2942
+ /**
2943
+ * Source of the effective thresholds. Omitted when thresholds are global.
2944
+ */
2945
+ threshold_source?: (ThresholdSource | null)
2918
2946
  /**
2919
2947
  * Machine-actionable fix and suppress hints.
2920
2948
  */
@@ -2964,6 +2992,14 @@ weight: number
2964
2992
  */
2965
2993
  nesting: number
2966
2994
  }
2995
+ /**
2996
+ * Resolved thresholds used to evaluate a health finding.
2997
+ */
2998
+ export interface HealthEffectiveThresholds {
2999
+ max_cyclomatic: number
3000
+ max_cognitive: number
3001
+ max_crap: number
3002
+ }
2967
3003
  /**
2968
3004
  * Suggested action attached to a [`ComplexityViolation`].
2969
3005
  *
@@ -3046,6 +3082,36 @@ severity_critical_count: number
3046
3082
  severity_high_count: number
3047
3083
  severity_moderate_count: number
3048
3084
  }
3085
+ /**
3086
+ * Report entry describing whether a threshold override is active, stale, or
3087
+ * no longer matching any analyzed file or function.
3088
+ */
3089
+ export interface ThresholdOverrideState {
3090
+ status: ThresholdOverrideStatus
3091
+ override_index: number
3092
+ path?: (string | null)
3093
+ function?: (string | null)
3094
+ configured_thresholds: HealthConfiguredThresholds
3095
+ effective_thresholds: HealthEffectiveThresholds
3096
+ metrics?: (ThresholdOverrideMetrics | null)
3097
+ reason?: (string | null)
3098
+ }
3099
+ /**
3100
+ * Threshold values configured by a single override entry.
3101
+ */
3102
+ export interface HealthConfiguredThresholds {
3103
+ max_cyclomatic?: (number | null)
3104
+ max_cognitive?: (number | null)
3105
+ max_crap?: (number | null)
3106
+ }
3107
+ /**
3108
+ * Current complexity metrics for a matched threshold override entry.
3109
+ */
3110
+ export interface ThresholdOverrideMetrics {
3111
+ cyclomatic: number
3112
+ cognitive: number
3113
+ crap?: (number | null)
3114
+ }
3049
3115
  /**
3050
3116
  * Project-wide vital signs , a fixed set of metrics for trend tracking.
3051
3117
  *
@@ -4609,6 +4675,11 @@ elapsed_ms: ElapsedMs
4609
4675
  */
4610
4676
  findings: HealthFinding[]
4611
4677
  summary: HealthSummary
4678
+ /**
4679
+ * Configured threshold override states. Entries are emitted for active
4680
+ * exceptions, stale exceptions, and full-run no-match cleanup hints.
4681
+ */
4682
+ threshold_overrides?: ThresholdOverrideState[]
4612
4683
  /**
4613
4684
  * Project-wide vital signs (always computed from available data).
4614
4685
  */
@@ -5144,6 +5215,7 @@ misconfigured_dependency_overrides?: MisconfiguredDependencyOverrideFinding[]
5144
5215
  export interface ImpactReport {
5145
5216
  schema_version: ImpactReportSchemaVersion
5146
5217
  enabled: boolean
5218
+ enabled_source: EnabledSource
5147
5219
  record_count: number
5148
5220
  _meta?: (Meta | null)
5149
5221
  first_recorded?: (string | null)
@@ -5207,7 +5279,8 @@ recent_resolved: ResolutionEvent[]
5207
5279
  attribution_active: boolean
5208
5280
  /**
5209
5281
  * Whether the local agent onboarding prompt has been explicitly declined.
5210
- * Stored under `.fallow/` so agents can avoid cross-session nags.
5282
+ * Stored in the user config dir (per project) so agents avoid cross-session
5283
+ * nags without writing into the repo.
5211
5284
  */
5212
5285
  onboarding_declined: boolean
5213
5286
  /**