fallow 2.102.0 → 2.103.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.102.0",
3
+ "version": "2.103.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.1.1"
84
84
  },
85
85
  "optionalDependencies": {
86
- "@fallow-cli/darwin-arm64": "2.102.0",
87
- "@fallow-cli/darwin-x64": "2.102.0",
88
- "@fallow-cli/linux-x64-gnu": "2.102.0",
89
- "@fallow-cli/linux-arm64-gnu": "2.102.0",
90
- "@fallow-cli/linux-x64-musl": "2.102.0",
91
- "@fallow-cli/linux-arm64-musl": "2.102.0",
92
- "@fallow-cli/win32-arm64-msvc": "2.102.0",
93
- "@fallow-cli/win32-x64-msvc": "2.102.0"
86
+ "@fallow-cli/darwin-arm64": "2.103.0",
87
+ "@fallow-cli/darwin-x64": "2.103.0",
88
+ "@fallow-cli/linux-x64-gnu": "2.103.0",
89
+ "@fallow-cli/linux-arm64-gnu": "2.103.0",
90
+ "@fallow-cli/linux-x64-musl": "2.103.0",
91
+ "@fallow-cli/linux-arm64-musl": "2.103.0",
92
+ "@fallow-cli/win32-arm64-msvc": "2.103.0",
93
+ "@fallow-cli/win32-x64-msvc": "2.103.0"
94
94
  }
95
95
  }
@@ -107,10 +107,10 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
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
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
- | `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` |
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`, `--css`, `--complexity-breakdown`, `--min-severity`, `--report-only`, `--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` |
113
- | `audit` | Combined dead-code + complexity + duplication for changed files | `--base`, `--gate`, `--production`, `--production-dead-code`, `--production-health`, `--production-dupes`, `--workspace`, `--changed-workspaces`, `--ci`, `--fail-on-issues`, `--explain`, `--explain-skipped`, `--dead-code-baseline`, `--health-baseline`, `--dupes-baseline`, `--max-crap`, `--coverage`, `--coverage-root`, `--include-entry-exports` |
113
+ | `audit` | Combined dead-code + complexity + duplication for changed files, returns a verdict; `fallow review` is an alias for `fallow audit --brief` (advisory orientation brief, always exits 0) | `--base`, `--gate`, `--brief`, `--max-decisions`, `--walkthrough-guide`, `--walkthrough-file`, `--show-deprioritized`, `--production`, `--production-dead-code`, `--production-health`, `--production-dupes`, `--workspace`, `--changed-workspaces`, `--ci`, `--fail-on-issues`, `--explain`, `--explain-skipped`, `--dead-code-baseline`, `--health-baseline`, `--dupes-baseline`, `--max-crap`, `--coverage`, `--coverage-root`, `--include-entry-exports` |
114
114
  | `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` |
115
115
  | `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` |
116
116
  | `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` |
@@ -149,10 +149,11 @@ Run `fallow <command> --help` for the full flag list per command (see also refer
149
149
  | `circular-dependency` | `--circular-deps` | - | `// fallow-ignore-next-line circular-dependency` | Import cycles in the module graph |
150
150
  | `re-export-cycle` | `--re-export-cycles` | - | `// fallow-ignore-file re-export-cycle` | Barrel files re-exporting from each other in a loop (`kind: "multi-node"`) or a barrel re-exporting from itself (`kind: "self-loop"`). Chain propagation through the loop is a structural no-op so imports through any member may silently come up empty. Default `warn`. Distinct from `circular-dependencies` (runtime cycles, sometimes intentional). File-scoped suppression only: `// fallow-ignore-file re-export-cycle` on any member breaks the cycle. |
151
151
  | `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 |
152
- | `boundary-coverage` | - | - | `// fallow-ignore-file boundary-violation` | Source file matches no configured architecture boundary zone; Requires boundaries.coverage.requireAllFiles |
153
- | `boundary-call-violation` | - | - | `// fallow-ignore-next-line boundary-call-violation` | Zoned file calls a callee its zone forbids; Requires boundaries.calls.forbidden patterns |
152
+ | `boundary-coverage` | `--boundary-violations` | - | `// fallow-ignore-file boundary-violation` | Source file matches no configured architecture boundary zone; Requires boundaries.coverage.requireAllFiles |
153
+ | `boundary-call-violation` | `--boundary-violations` | - | `// fallow-ignore-next-line boundary-call-violation` | Zoned file calls a callee its zone forbids; Requires boundaries.calls.forbidden patterns |
154
154
  | `policy-violation` | `--policy-violations` | - | `// fallow-ignore-next-line policy-violation` | Calls, imports, or catalogue-derived effects banned by a declarative rule pack (`rulePacks` config key lists standalone JSON/JSONC files of `banned-call`, `banned-import`, and `banned-effect` 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. |
155
155
  | `stale-suppression` | `--stale-suppressions` | - | - | `fallow-ignore` comments or `@expected-unused` JSDoc tags that no longer match any issue |
156
+ | `missing-suppression-reason` | - | - | - | Suppression comment omits a required reason |
156
157
  | `unused-catalog-entry` | `--unused-catalog-entries` | yes | - | `pnpm-workspace.yaml` entries no workspace package.json references via `catalog:` (default `warn`) |
157
158
  | `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`. |
158
159
  | `unresolved-catalog-reference` | `--unresolved-catalog-references` | - | - | `package.json` references to `catalog:` / `catalog:<name>` whose catalog does not declare the package; `pnpm install` would fail. Default `error`. Suppress via `ignoreCatalogReferences: [{ package, catalog?, consumer? }]` in fallow config (package.json has no comment syntax). |
@@ -442,7 +443,7 @@ When `--format json` is active and exit code is 2, errors are emitted as JSON on
442
443
 
443
444
  ## Configuration
444
445
 
445
- Fallow reads config from project root: `.fallowrc.json` > `.fallowrc.jsonc` > `fallow.toml` > `.fallow.toml`. Both `.fallowrc.json` and `.fallowrc.jsonc` accept JSON-with-comments syntax (same parser); the `.jsonc` extension lets editors auto-detect JSONC syntax highlighting. Most projects work with zero configuration thanks to 121 auto-detecting framework plugins.
446
+ Fallow reads config from project root: `.fallowrc.json` > `.fallowrc.jsonc` > `fallow.toml` > `.fallow.toml`. Both `.fallowrc.json` and `.fallowrc.jsonc` accept JSON-with-comments syntax (same parser); the `.jsonc` extension lets editors auto-detect JSONC syntax highlighting. Most projects work with zero configuration thanks to 122 auto-detecting framework plugins.
446
447
 
447
448
  ```jsonc
448
449
  {
@@ -17,6 +17,8 @@ Complete command and flag specifications for all fallow CLI commands.
17
17
  - [`flags`: Feature Flag Detection](#flags-feature-flag-detection)
18
18
  - [`security`: Security Candidate Detection](#security-security-candidate-detection)
19
19
  - [`inspect`: Target Evidence Bundle](#inspect-target-evidence-bundle)
20
+ - [`trace`: Symbol Call Chains](#trace-symbol-call-chains)
21
+ - [`decision-surface`: Structural Decisions](#decision-surface-structural-decisions)
20
22
  - [`explain`: Rule Explanation](#explain-rule-explanation)
21
23
  - [`schema`: CLI Introspection](#schema-cli-introspection)
22
24
  - [`config-schema`: Config JSON Schema](#config-schema-config-json-schema)
@@ -506,7 +508,7 @@ fallow health --format json --quiet --trend
506
508
  {
507
509
  "kind": "health",
508
510
  "schema_version": 7,
509
- "version": "2.102.0",
511
+ "version": "2.103.0",
510
512
  "elapsed_ms": 32,
511
513
  "summary": {
512
514
  "files_analyzed": 482,
@@ -898,7 +900,7 @@ fallow audit \
898
900
  {
899
901
  "kind": "audit",
900
902
  "schema_version": 7,
901
- "version": "2.102.0",
903
+ "version": "2.103.0",
902
904
  "command": "audit",
903
905
  "verdict": "fail",
904
906
  "changed_files_count": 12,
@@ -973,7 +975,7 @@ fallow flags --format json --quiet --workspace my-package
973
975
  ```json
974
976
  {
975
977
  "schema_version": 7,
976
- "version": "2.102.0",
978
+ "version": "2.103.0",
977
979
  "elapsed_ms": 116,
978
980
  "feature_flags": [],
979
981
  "total_flags": 0
@@ -1036,6 +1038,7 @@ The second rule family is a data-driven `tainted-sink` catalogue: syntactic dang
1036
1038
  | `secret-pii-log` | 532 | source-backed secrets or request PII reaching logs |
1037
1039
  | `hardcoded-secret` | 798 | provider-prefix credentials and high-entropy literals assigned to secret-shaped identifiers (include-required) |
1038
1040
  | `secret-to-network` | 201 | a non-public `process.env` / `import.meta.env` secret reaching a network call body (`fetch` / `axios` / `got` / ...) via same-identifier flow (include-required) |
1041
+ | `llm-call-injection` | 1427 | an untrusted source reaching the prompt/messages argument of a known LLM-call sink (taint-path gated, pinned to distinctive LLM SDK call shapes) |
1039
1042
  | `xpath-injection` | 643 | `xpath.select` / `select1` with a non-literal expression |
1040
1043
 
1041
1044
  Build-config and test files are excluded from candidate generation. Security rule families default to `off` and are surfaced only by `fallow security`, never under bare `fallow` or the `audit` gate. Scope which catalogue categories run with `security.categories` include / exclude lists in config. 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. The setting is additive only and does not gate `*.searchParams`. `hardcoded-secret` and `secret-to-network` are intentionally include-required and only run when listed in `security.categories.include` (`secret-to-network` is opt-in because legitimate auth is also a secret reaching a network call). Public-by-convention env vars (`NEXT_PUBLIC_`, `VITE_`, ...) are never treated as secrets.
@@ -1073,7 +1076,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1073
1076
  {
1074
1077
  "kind": "security",
1075
1078
  "schema_version": "4",
1076
- "version": "2.102.0",
1079
+ "version": "2.103.0",
1077
1080
  "elapsed_ms": 42,
1078
1081
  "config": {
1079
1082
  "rules": {
@@ -1102,7 +1105,7 @@ fallow security --gate newly-reachable --changed-since origin/main
1102
1105
  {
1103
1106
  "kind": "security",
1104
1107
  "schema_version": "4",
1105
- "version": "2.102.0",
1108
+ "version": "2.103.0",
1106
1109
  "elapsed_ms": 42,
1107
1110
  "config": {
1108
1111
  "rules": {
@@ -1215,6 +1218,48 @@ Each evidence section carries `status` and `scope`. Non-fatal child-analysis fai
1215
1218
 
1216
1219
  ---
1217
1220
 
1221
+ ## `trace`: Symbol Call Chains
1222
+
1223
+ Walk the callers and callees of one exported symbol through the module graph. Callers are the modules that import the symbol (walked up); callees are the symbol's module's import-symbol edges plus its intra-module call sites (walked down). Best-effort and syntactic per ADR-001: resolved and unresolved callees are reported honestly, never silently dropped. This is its own surface, never folded into the ranked review brief.
1224
+
1225
+ The target is a positional argument, formatted as `FILE:SYMBOL` (for example `src/utils.ts:formatDate`). When neither `--callers` nor `--callees` is given, both directions are walked.
1226
+
1227
+ ```bash
1228
+ fallow trace src/utils.ts:formatDate
1229
+ fallow trace src/utils.ts:formatDate --callers --depth 3
1230
+ ```
1231
+
1232
+ <!-- generated:flags:trace:start -->
1233
+ | Flag | Type | Default | Description |
1234
+ |---|---|---|---|
1235
+ | `--callers` | `bool` | `false` | Walk UP to callers (modules that import the symbol). When neither `--callers` nor `--callees` is set, both directions are walked |
1236
+ | `--callees` | `bool` | `false` | Walk DOWN to callees (the symbol's module's import-symbol edges plus unresolved call sites). When neither flag is set, both are walked |
1237
+ | `--depth` | `string` | - | Chain depth bound for both directions (default 2). Symbol-level is best-effort, so a shallow bound keeps the trace legible |
1238
+
1239
+ Common global flags for this command: [`--format`](#global-flags), [`--quiet`](#global-flags), [`--root`](#global-flags), [`--config`](#global-flags).
1240
+ <!-- generated:flags:trace:end -->
1241
+
1242
+ ---
1243
+
1244
+ ## `decision-surface`: Structural Decisions
1245
+
1246
+ Surface only the consequential structural decisions a change embeds (the apex of the review brief): a ranked, capped (3 to 5, default 4) set of coupling/boundary, public-API/contract, and dependency decisions, each framed as a judgment question with the routed expert to ask, plus a trade-off clause and the count of in-repo consumers that already depend on the anchor. Runs the same changed-code analysis as `fallow review` but emits only the decisions, separable and cheap. Always exits 0 (advisory, never a gate); every decision is suppressible with `// fallow-ignore`. Use `--base` / `--changed-since` to pick the comparison point, exactly like `fallow audit`.
1247
+
1248
+ ```bash
1249
+ fallow decision-surface --base main
1250
+ fallow decision-surface --base main --format json --quiet
1251
+ ```
1252
+
1253
+ <!-- generated:flags:decision-surface:start -->
1254
+ | Flag | Type | Default | Description |
1255
+ |---|---|---|---|
1256
+ | `--max-decisions` | `string` | `4` | Cap on the number of surfaced decisions (the working-memory limit). Default 4; clamped to the 3-5 band (4 plus or minus 1) |
1257
+
1258
+ Common global flags for this command: [`--changed-since`](#global-flags), [`--format`](#global-flags), [`--quiet`](#global-flags), [`--workspace`](#global-flags), [`--root`](#global-flags), [`--config`](#global-flags).
1259
+ <!-- generated:flags:decision-surface:end -->
1260
+
1261
+ ---
1262
+
1218
1263
  ## `explain`: Rule Explanation
1219
1264
 
1220
1265
  Print rule rationale, examples, fix guidance, and docs URL for one issue type without running analysis.
@@ -1768,7 +1813,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
1768
1813
  {
1769
1814
  "kind": "dead-code",
1770
1815
  "schema_version": 7,
1771
- "version": "2.102.0",
1816
+ "version": "2.103.0",
1772
1817
  "elapsed_ms": 45,
1773
1818
  "total_issues": 12,
1774
1819
  "entry_points": {
@@ -1928,7 +1973,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
1928
1973
  {
1929
1974
  "kind": "dupes",
1930
1975
  "schema_version": 7,
1931
- "version": "2.102.0",
1976
+ "version": "2.103.0",
1932
1977
  "elapsed_ms": 82,
1933
1978
  "total_clones": 15,
1934
1979
  "total_lines_duplicated": 230,
@@ -1972,11 +2017,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
1972
2017
  {
1973
2018
  "kind": "combined",
1974
2019
  "schema_version": 7,
1975
- "version": "2.102.0",
2020
+ "version": "2.103.0",
1976
2021
  "elapsed_ms": 159,
1977
2022
  "check": {
1978
2023
  "schema_version": 7,
1979
- "version": "2.102.0",
2024
+ "version": "2.103.0",
1980
2025
  "elapsed_ms": 45,
1981
2026
  "total_issues": 12,
1982
2027
  "unused_files": [],
@@ -23,7 +23,7 @@ Always preview with `--dry-run` before applying. This is a destructive operation
23
23
 
24
24
  ## Don't Create Config Unless Needed
25
25
 
26
- Fallow works with zero configuration for most projects thanks to 121 auto-detecting framework plugins. Creating an unnecessary config file can mask issues or override detection behavior.
26
+ Fallow works with zero configuration for most projects thanks to 122 auto-detecting framework plugins. Creating an unnecessary config file can mask issues or override detection behavior.
27
27
 
28
28
  ```bash
29
29
  # WRONG: creating config for a standard Next.js project
@@ -67,7 +67,7 @@ The `--changed-since` flag limits analysis to files modified since a git ref. It
67
67
  # This only shows issues in files changed since main
68
68
  fallow dead-code --format json --quiet --changed-since main
69
69
 
70
- # Same for duplication only clone groups involving changed files
70
+ # Same for duplication, only clone groups involving changed files
71
71
  fallow dupes --format json --quiet --changed-since main
72
72
 
73
73
  # This shows ALL issues in the project
@@ -577,7 +577,7 @@ Fallow detects production dependencies that are only imported from test files (`
577
577
  // src/handlers.test.ts
578
578
  import { setupServer } from 'msw/node'; // Flagged as test-only dependency
579
579
 
580
- // src/app.ts no imports of "msw" here
580
+ // src/app.ts: no imports of "msw" here
581
581
  ```
582
582
 
583
583
  ```bash
@@ -596,8 +596,8 @@ The `test-only-dependencies` rule defaults to `warn`. Suppress with `"test-only-
596
596
 
597
597
  These are separate features and can be used independently or together:
598
598
 
599
- - **`FALLOW_COMMENT: "true"`** posts a single summary comment on the MR with issue counts and a findings table
600
- - **`FALLOW_REVIEW: "true"`** posts inline code review comments on the exact MR diff lines where issues were found
599
+ - **`FALLOW_COMMENT: "true"`**: posts a single summary comment on the MR with issue counts and a findings table
600
+ - **`FALLOW_REVIEW: "true"`**: posts inline code review comments on the exact MR diff lines where issues were found
601
601
 
602
602
  ```yaml
603
603
  # WRONG: expecting inline review comments from FALLOW_COMMENT
@@ -658,7 +658,7 @@ variables:
658
658
  FALLOW_CHANGED_SINCE: "origin/main"
659
659
 
660
660
  # CORRECT: let the template auto-detect
661
- # (no FALLOW_CHANGED_SINCE needed it reads the MR target branch)
661
+ # (no FALLOW_CHANGED_SINCE needed, it reads the MR target branch)
662
662
  ```
663
663
 
664
664
  Override `FALLOW_CHANGED_SINCE` only when you need a specific ref (e.g., a release branch) or want to disable auto-detection by setting it to an empty string.
@@ -669,4 +669,4 @@ Override `FALLOW_CHANGED_SINCE` only when you need a specific ref (e.g., a relea
669
669
 
670
670
  The GitLab CI template auto-detects the project's package manager from lockfiles (`package-lock.json` for npm, `pnpm-lock.yaml` for pnpm, `yarn.lock` for yarn). MR comments and review comments use the correct commands for the detected manager.
671
671
 
672
- This means review comments will show `pnpm remove lodash` instead of `npm uninstall lodash` in a pnpm project. No configuration is needed detection is automatic.
672
+ This means review comments will show `pnpm remove lodash` instead of `npm uninstall lodash` in a pnpm project. No configuration is needed; detection is automatic.
@@ -222,7 +222,7 @@ fallow:
222
222
  FALLOW_FAIL_ON_ISSUES: "true"
223
223
  ```
224
224
 
225
- Generates Code Quality reports (inline MR annotations) automatically. In MR pipelines, `--changed-since` is automatically set to the target branch no manual configuration needed.
225
+ Generates Code Quality reports (inline MR annotations) automatically. In MR pipelines, `--changed-since` is automatically set to the target branch; no manual configuration needed.
226
226
 
227
227
  If runners cannot reach `raw.githubusercontent.com`, run `fallow ci-template gitlab --vendor`, commit the generated `ci/` and `action/` files, and use GitLab's local include syntax:
228
228
 
@@ -494,9 +494,9 @@ fallow dupes --format json --quiet
494
494
  | jscpd | fallow |
495
495
  |-------|--------|
496
496
  | Default (exact tokens) | `strict` |
497
- | | `mild` (fallow default, syntax normalized) |
498
- | | `weak` (literal normalization) |
499
- | | `semantic` (variable rename detection) |
497
+ | n/a | `mild` (fallow default, syntax normalized) |
498
+ | n/a | `weak` (literal normalization) |
499
+ | n/a | `semantic` (variable rename detection) |
500
500
 
501
501
  ---
502
502
 
@@ -119,6 +119,9 @@ export type SchemaVersion = 7
119
119
  * a bare string (e.g. `"2.74.0"`).
120
120
  */
121
121
  export type ToolVersion = string
122
+ /**
123
+ * Audit command singleton carried by [`AuditOutput`].
124
+ */
122
125
  export type AuditCommand = "audit"
123
126
  /**
124
127
  * Verdict for the audit command.
@@ -450,7 +453,8 @@ export type UntestedFileActionType = ("add-tests" | "suppress-file")
450
453
  */
451
454
  export type UntestedExportActionType = ("add-test-import" | "suppress-file")
452
455
  /**
453
- * Churn trend indicator based on comparing recent vs older halves of the analysis period.
456
+ * Churn trend indicator based on comparing recent vs older halves of the
457
+ * analysis period.
454
458
  */
455
459
  export type ChurnTrend = ("accelerating" | "stable" | "cooling")
456
460
  export type ContributorIdentifierFormat = ("raw" | "handle" | "anonymized" | "hash")
@@ -851,7 +855,7 @@ duplication?: (DupesReportPayload | null)
851
855
  complexity?: (HealthReport | null)
852
856
  /**
853
857
  * Read-only follow-up commands computed from this run's findings. See
854
- * [`CheckOutput::next_steps`] for the contract.
858
+ * `CheckOutput::next_steps` for the contract.
855
859
  */
856
860
  next_steps?: NextStep[]
857
861
  }
@@ -3611,7 +3615,7 @@ reason: string
3611
3615
  }
3612
3616
  /**
3613
3617
  * Wire-shape payload for `fallow dupes --format json` (the body that
3614
- * flattens into [`crate::output_envelope::DupesOutput`] and is also
3618
+ * flattens into the `DupesOutput` envelope and is also
3615
3619
  * emitted under the `dupes` / `duplication` key inside the combined and
3616
3620
  * audit envelopes).
3617
3621
  *
@@ -3627,8 +3631,8 @@ export interface DupesReportPayload {
3627
3631
  clone_groups: CloneGroupFinding[]
3628
3632
  /**
3629
3633
  * Clone families, each wrapped with typed actions. Inner `groups`
3630
- * inside each [`CloneFamilyFinding`] are themselves wrapped as
3631
- * [`CloneGroupFinding`] entries carrying their own `actions[]` (and
3634
+ * inside each `CloneFamilyFinding` are themselves wrapped as
3635
+ * `CloneGroupFinding` entries carrying their own `actions[]` (and
3632
3636
  * optional audit-mode `introduced` flag), so JSON-Schema strict
3633
3637
  * consumers and TS consumers reading `clone_families[].groups[]` see
3634
3638
  * the same shape as the top-level `clone_groups[]` array (preserves
@@ -3718,8 +3722,8 @@ end_col: number
3718
3722
  fragment: string
3719
3723
  }
3720
3724
  /**
3721
- * Per-action wire shape attached to each [`CloneGroupFinding`] and
3722
- * [`AttributedCloneGroupFinding`]. Mirrors the action types previously
3725
+ * Per-action wire shape attached to each `CloneGroupFinding` and
3726
+ * `AttributedCloneGroupFinding`. Mirrors the action types previously
3723
3727
  * emitted by `inject_dupes_actions::build_clone_group_actions` in
3724
3728
  * `crates/cli/src/report/json.rs`: `extract-shared` plus `suppress-line`.
3725
3729
  */
@@ -3748,7 +3752,7 @@ comment?: (string | null)
3748
3752
  * Unlike most `*Finding` wrappers this one is NOT `#[serde(flatten)]` over
3749
3753
  * the bare [`CloneFamily`], because the family's nested
3750
3754
  * `groups: Vec<CloneGroup>` field needs to carry the typed
3751
- * [`CloneGroupFinding`] wrapper too (so every nested clone group gets its
3755
+ * `CloneGroupFinding` wrapper too (so every nested clone group gets its
3752
3756
  * own `actions[]` array, matching the legacy post-pass behavior; see issue
3753
3757
  * #393 regression test). The wire shape stays byte-identical to the
3754
3758
  * previous post-pass output. No `introduced` field because `fallow audit`
@@ -3756,7 +3760,7 @@ comment?: (string | null)
3756
3760
  */
3757
3761
  export interface CloneFamilyFinding {
3758
3762
  /**
3759
- * The files involved in this family (sorted for stable output).
3763
+ * The files involved in this family.
3760
3764
  */
3761
3765
  files: string[]
3762
3766
  /**
@@ -3779,7 +3783,7 @@ total_duplicated_tokens: number
3779
3783
  suggestions: RefactoringSuggestion[]
3780
3784
  /**
3781
3785
  * Suggested next steps: an `extract-shared` primary, one
3782
- * `apply-suggestion` per [`RefactoringSuggestion`] on the family, and
3786
+ * `apply-suggestion` per `RefactoringSuggestion` on the family, and
3783
3787
  * a trailing `suppress-line`. Always emitted (possibly empty for
3784
3788
  * forward-compat).
3785
3789
  */
@@ -3800,10 +3804,10 @@ description: string
3800
3804
  estimated_savings: number
3801
3805
  }
3802
3806
  /**
3803
- * Per-action wire shape attached to each [`CloneFamilyFinding`]. Mirrors
3807
+ * Per-action wire shape attached to each `CloneFamilyFinding`. Mirrors
3804
3808
  * the action types previously emitted by
3805
3809
  * `build_clone_family_actions`: `extract-shared`, one `apply-suggestion`
3806
- * per [`RefactoringSuggestion`] on the family, and a trailing
3810
+ * per `RefactoringSuggestion` on the family, and a trailing
3807
3811
  * `suppress-line`.
3808
3812
  */
3809
3813
  export interface CloneFamilyAction {
@@ -3912,7 +3916,7 @@ export interface HealthReport {
3912
3916
  /**
3913
3917
  * Functions and synthetic template entries exceeding complexity
3914
3918
  * thresholds, sorted by the --sort criteria. Each entry wraps its
3915
- * inner [`ComplexityViolation`] payload (flattened on the wire) with
3919
+ * inner `ComplexityViolation` payload (flattened on the wire) with
3916
3920
  * the typed `actions` list and an optional audit-mode `introduced`
3917
3921
  * flag.
3918
3922
  */
@@ -3957,7 +3961,7 @@ prop_drilling_chains?: PropDrillingChainFinding[]
3957
3961
  /**
3958
3962
  * Hotspot entries combining git churn with complexity. Only present when
3959
3963
  * --hotspots is used. Sorted by score descending (highest risk first).
3960
- * Each entry wraps its inner [`HotspotEntry`] payload (flattened on the
3964
+ * Each entry wraps its inner `HotspotEntry` payload (flattened on the
3961
3965
  * wire) with a typed `actions` list.
3962
3966
  */
3963
3967
  hotspots?: HotspotFinding[]
@@ -3982,7 +3986,7 @@ large_functions?: LargeFunctionEntry[]
3982
3986
  /**
3983
3987
  * Ranked refactoring recommendations. Only present when --targets is used.
3984
3988
  * Sorted by efficiency (priority/effort) descending. Each entry wraps
3985
- * its inner [`RefactoringTarget`] payload (flattened on the wire) with
3989
+ * its inner `RefactoringTarget` payload (flattened on the wire) with
3986
3990
  * a typed `actions` list.
3987
3991
  */
3988
3992
  targets?: RefactoringTargetFinding[]
@@ -4189,7 +4193,7 @@ max_crap: number
4189
4193
  * `comment` plus `placement`, and the coverage-leaning actions
4190
4194
  * (`add-tests`, `increase-coverage`) carry only `note`.
4191
4195
  *
4192
- * [`ComplexityViolation`]: ../../fallow-cli/src/health_types/scores.rs
4196
+ * [`ComplexityViolation`]: ../../fallow-output/src/health_scores.rs
4193
4197
  */
4194
4198
  export interface HealthFindingAction {
4195
4199
  type: HealthFindingActionType
@@ -4287,7 +4291,7 @@ cognitive: number
4287
4291
  crap?: (number | null)
4288
4292
  }
4289
4293
  /**
4290
- * Project-wide vital signs , a fixed set of metrics for trend tracking.
4294
+ * Project-wide vital signs: a fixed set of metrics for trend tracking.
4291
4295
  *
4292
4296
  * Metrics are `Option` when the data source was not available in the current run
4293
4297
  * (e.g., `duplication_pct` is `None` unless the duplication pipeline was run,
@@ -4328,7 +4332,7 @@ hotspot_count?: (number | null)
4328
4332
  */
4329
4333
  hotspot_top_pct_count?: (number | null)
4330
4334
  /**
4331
- * Average maintainability index across all scored files (0100).
4335
+ * Average maintainability index across all scored files (0-100).
4332
4336
  */
4333
4337
  maintainability_avg?: (number | null)
4334
4338
  /**
@@ -4616,7 +4620,7 @@ path: string
4616
4620
  value_export_count: number
4617
4621
  /**
4618
4622
  * Suggested next steps: an `add-tests` primary and a `suppress-file`
4619
- * secondary. Always emitted (possibly empty for forward-compat).
4623
+ * secondary. Always emitted for the current wire contract.
4620
4624
  */
4621
4625
  actions: UntestedFileAction[]
4622
4626
  }
@@ -4630,7 +4634,7 @@ actions: UntestedFileAction[]
4630
4634
  * struct shape; the field that is populated (`note` for `add-tests`,
4631
4635
  * `comment` for `suppress-file`) depends on the `kind`.
4632
4636
  *
4633
- * [`UntestedFile`]: ../../fallow-cli/src/health_types/coverage.rs
4637
+ * [`UntestedFile`]: ../../fallow-output/src/health_coverage_gaps.rs
4634
4638
  */
4635
4639
  export interface UntestedFileAction {
4636
4640
  type: UntestedFileActionType
@@ -4693,7 +4697,7 @@ actions: UntestedExportAction[]
4693
4697
  * `add-test-import` reflects that a test-reachable reference chain, not
4694
4698
  * just any test coverage, is what closes the gap.
4695
4699
  *
4696
- * [`UntestedExport`]: ../../fallow-cli/src/health_types/coverage.rs
4700
+ * [`UntestedExport`]: ../../fallow-output/src/health_coverage_gaps.rs
4697
4701
  */
4698
4702
  export interface UntestedExportAction {
4699
4703
  type: UntestedExportActionType
@@ -4784,7 +4788,7 @@ commits: number
4784
4788
  * `ownership-drift`) are appended only when `--ownership` is active AND
4785
4789
  * the corresponding signal fires for the hotspot.
4786
4790
  *
4787
- * [`HotspotEntry`]: ../../fallow-cli/src/health_types/scores.rs
4791
+ * [`HotspotEntry`]: ../../fallow-output/src/health_scores.rs
4788
4792
  */
4789
4793
  export interface HotspotAction {
4790
4794
  type: HotspotActionType
@@ -4870,6 +4874,27 @@ watermark?: (RuntimeCoverageWatermark | null)
4870
4874
  * Non-fatal merge or coverage diagnostics. Omitted when empty.
4871
4875
  */
4872
4876
  warnings?: RuntimeCoverageMessage[]
4877
+ /**
4878
+ * Whether an autonomous agent may act on this report (fallow-rs/fallow-cloud#316,
4879
+ * mirrors the cloud runtime-context contract). `false` when the capture
4880
+ * carries no usable runtime evidence (no tracked functions); then
4881
+ * `actionability_verdict` is `insufficient_evidence` and
4882
+ * `actionability_reason` explains. F4: a non-action floor, never a gate on a
4883
+ * positive verdict.
4884
+ */
4885
+ actionable: boolean
4886
+ /**
4887
+ * Why the report is non-actionable; `null` when `actionable` is true.
4888
+ */
4889
+ actionability_reason?: (string | null)
4890
+ /**
4891
+ * First-class non-action verdict (`insufficient_evidence`) when not
4892
+ * actionable; `null` otherwise. Mirrors the cloud runtime-context `verdict`;
4893
+ * named distinctly from the report-context `verdict` above to avoid a
4894
+ * collision.
4895
+ */
4896
+ actionability_verdict?: (string | null)
4897
+ provenance: RuntimeCoverageProvenance
4873
4898
  }
4874
4899
  /**
4875
4900
  * Summary block mirroring `fallow_cov_protocol::Summary` (0.3 shape).
@@ -4910,7 +4935,7 @@ coverage_percent: number
4910
4935
  trace_count: number
4911
4936
  /**
4912
4937
  * Days of observation covered by the supplied dump (Phase 2 local analysis
4913
- * emits 0 , set by the beacon/cloud in Phase 3+).
4938
+ * emits 0, set by the beacon/cloud in Phase 3+).
4914
4939
  */
4915
4940
  period_days: number
4916
4941
  /**
@@ -5005,6 +5030,13 @@ evidence: RuntimeCoverageEvidence
5005
5030
  * Suggested actions for this finding. Omitted when empty.
5006
5031
  */
5007
5032
  actions?: RuntimeCoverageAction[]
5033
+ /**
5034
+ * The discriminator inputs that produced this verdict (#321), emitted so an
5035
+ * agent can reproduce it and see the confidence cap. `None` for findings
5036
+ * not built from the merge pipeline (e.g. baseline round-trips). Omitted
5037
+ * from JSON when absent.
5038
+ */
5039
+ discriminators?: (RuntimeCoverageDiscriminators | null)
5008
5040
  }
5009
5041
  /**
5010
5042
  * Supporting evidence for a finding (mirrors `fallow_cov_protocol::Evidence`).
@@ -5057,6 +5089,48 @@ description: string
5057
5089
  */
5058
5090
  auto_fixable: boolean
5059
5091
  }
5092
+ /**
5093
+ * Discriminator inputs that PRODUCED a finding's verdict (fallow-rs/fallow-cloud#321),
5094
+ * emitted alongside the verdict so an agent can reproduce it and see the
5095
+ * minimum-observation confidence cap instead of re-deriving them from scratch.
5096
+ * F4: these make the EXISTING Fallow-owned discriminators legible; they are not
5097
+ * a new or external signal and gate nothing. Pairs with `evidence.static_status`
5098
+ * (the static half of the discriminator set).
5099
+ */
5100
+ export interface RuntimeCoverageDiscriminators {
5101
+ /**
5102
+ * Three-state runtime tracking: `called` (invocations > 0), `never_called`
5103
+ * (V8 tracked it, invocations == 0), or `untracked` (V8 never saw it). The
5104
+ * ONLY signal that can issue a deletion verdict.
5105
+ */
5106
+ tracking_state: string
5107
+ /**
5108
+ * `invocations / trace_count` for this function; `null` when untracked (no
5109
+ * invocation count). The per-function value behind the low-traffic split.
5110
+ */
5111
+ invocation_ratio?: (number | null)
5112
+ /**
5113
+ * Active/low_traffic split ratio in effect (CLI default 0.001). A tracked
5114
+ * function whose `invocation_ratio` is below this reads `low_traffic`, else
5115
+ * `active`.
5116
+ */
5117
+ low_traffic_threshold: number
5118
+ /**
5119
+ * Total observed invocations across all functions (the `invocation_ratio`
5120
+ * denominator), echoed per finding so the verdict is self-contained.
5121
+ */
5122
+ trace_count: number
5123
+ /**
5124
+ * High-confidence verdict floor (CLI default 5000). When `trace_count` is
5125
+ * below it, confidence is capped regardless of the per-function signal.
5126
+ */
5127
+ min_observation_volume: number
5128
+ /**
5129
+ * `trace_count >= min_observation_volume`: whether the dump cleared the
5130
+ * confidence floor. `false` means this verdict's confidence is capped.
5131
+ */
5132
+ meets_observation_volume: boolean
5133
+ }
5060
5134
  export interface RuntimeCoverageHotPath {
5061
5135
  /**
5062
5136
  * Stable content-hash ID of the form `fallow:hot:<hash>`.
@@ -5194,6 +5268,44 @@ code: string
5194
5268
  */
5195
5269
  message: string
5196
5270
  }
5271
+ /**
5272
+ * Provenance of a runtime-coverage report (fallow-rs/fallow-cloud#319), mirroring
5273
+ * the cloud runtime-context `provenance` block so the local-capture and cloud
5274
+ * surfaces present one portable shape. F4: provenance is context only; it never
5275
+ * gates a verdict or confidence.
5276
+ */
5277
+ export interface RuntimeCoverageProvenance {
5278
+ data_source: RuntimeCoverageDataSource
5279
+ /**
5280
+ * `true` / `false` / `unknown`. Always `unknown` for a local capture: the
5281
+ * local path has no deployment-origin signal (the cloud may resolve it).
5282
+ */
5283
+ is_production: string
5284
+ /**
5285
+ * Age in whole days of the most recent evidence; `0` for a fresh local
5286
+ * capture, `null` when no runtime data is present.
5287
+ */
5288
+ freshness_days?: (number | null)
5289
+ /**
5290
+ * `functions_untracked / (functions_tracked + functions_untracked)`, in
5291
+ * `[0, 1]`. High ratios mark a thin / partial capture.
5292
+ */
5293
+ untracked_ratio: number
5294
+ /**
5295
+ * Fraction of resolution-attempted functions whose position could not be
5296
+ * mapped to source, in `[0, 1]`. `0` for a local capture (positions resolve
5297
+ * natively or via the sidecar).
5298
+ */
5299
+ unresolved_ratio: number
5300
+ /**
5301
+ * Whether `freshness_days` exceeds `stale_after_days`.
5302
+ */
5303
+ stale: boolean
5304
+ /**
5305
+ * The documented staleness cutoff (days), echoed so the rule travels in-band.
5306
+ */
5307
+ stale_after_days: number
5308
+ }
5197
5309
  /**
5198
5310
  * Combined coverage, runtime, complexity, and change-scope verdicts.
5199
5311
  */
@@ -5465,7 +5577,7 @@ fingerprint: string
5465
5577
  * the target's `evidence.complex_functions` back to the matching
5466
5578
  * `ComplexityViolation` and read placement from THAT action instead.
5467
5579
  *
5468
- * [`RefactoringTarget`]: ../../fallow-cli/src/health_types/targets.rs
5580
+ * [`RefactoringTarget`]: ../../fallow-output/src/health_targets.rs
5469
5581
  */
5470
5582
  export interface RefactoringTargetAction {
5471
5583
  type: RefactoringTargetActionType
@@ -5483,7 +5595,7 @@ description: string
5483
5595
  /**
5484
5596
  * Recommendation category for `apply-refactoring` actions. Mirrors
5485
5597
  * the parent target's
5486
- * [`category`](../../fallow-cli/src/health_types/targets.rs.html)
5598
+ * [`category`](../../fallow-output/src/health_targets.rs.html)
5487
5599
  * field so consumers can route on the action alone.
5488
5600
  */
5489
5601
  category?: (string | null)
@@ -5567,11 +5679,11 @@ snapshot_schema_version?: (number | null)
5567
5679
  */
5568
5680
  export interface TrendMetric {
5569
5681
  /**
5570
- * Metric identifier (e.g., `"score"`, `"dead_file_pct"`).
5682
+ * Metric identifier, e.g. `"score"` or `"dead_file_pct"`.
5571
5683
  */
5572
5684
  name: string
5573
5685
  /**
5574
- * Human-readable label (e.g., `"Health Score"`, `"Dead Files"`).
5686
+ * Human-readable label, e.g. `"Health Score"` or `"Dead Files"`.
5575
5687
  */
5576
5688
  label: string
5577
5689
  /**
@@ -5583,12 +5695,12 @@ previous: number
5583
5695
  */
5584
5696
  current: number
5585
5697
  /**
5586
- * Absolute change (current previous).
5698
+ * Absolute change (current - previous).
5587
5699
  */
5588
5700
  delta: number
5589
5701
  direction: TrendDirection
5590
5702
  /**
5591
- * Unit for display (e.g., `"%"`, `""`, `"pts"`).
5703
+ * Unit for display, e.g. `"%"`, `""`, or `"pts"`.
5592
5704
  */
5593
5705
  unit: string
5594
5706
  /**
@@ -5605,11 +5717,11 @@ current_count?: (TrendCount | null)
5605
5717
  */
5606
5718
  export interface TrendCount {
5607
5719
  /**
5608
- * The numerator (e.g., dead files count).
5720
+ * The numerator, e.g. dead files count.
5609
5721
  */
5610
5722
  value: number
5611
5723
  /**
5612
- * The denominator (e.g., total files).
5724
+ * The denominator, e.g. total files.
5613
5725
  */
5614
5726
  total: number
5615
5727
  }
@@ -5617,10 +5729,10 @@ total: number
5617
5729
  * Auditable breadcrumb recording when health-finding `suppress-line`
5618
5730
  * action hints were omitted from the report.
5619
5731
  *
5620
- * Set at construction time on [`HealthReport::actions_meta`] (and on
5621
- * each [`HealthGroup::actions_meta`](crate::health_types::HealthGroup)
5732
+ * Set at construction time on `HealthReport::actions_meta` (and on
5733
+ * each `HealthGroup::actions_meta`
5622
5734
  * when grouped) by the report builder, derived from the active
5623
- * [`HealthActionContext`]. Lets consumers see "where did the
5735
+ * `HealthActionContext`. Lets consumers see "where did the
5624
5736
  * suppress-line hints go?" without having to grep the config or CLI
5625
5737
  * history.
5626
5738
  *
@@ -5632,8 +5744,8 @@ total: number
5632
5744
  */
5633
5745
  export interface HealthActionsMeta {
5634
5746
  /**
5635
- * Always `true` when the breadcrumb is emitted. Absent from the wire
5636
- * when no suppression occurred.
5747
+ * Always `true` when the breadcrumb is emitted. Absent from the wire when
5748
+ * no suppression occurred.
5637
5749
  */
5638
5750
  suppression_hints_omitted: boolean
5639
5751
  /**
@@ -6648,10 +6760,9 @@ _meta?: (Meta | null)
6648
6760
  }
6649
6761
  /**
6650
6762
  * Envelope emitted by `fallow list --boundaries --format json`. Surfaces
6651
- * the architecture boundary zones, rules, and (issue #373) the user's
6652
- * pre-expansion `autoDiscover` logical groups so consumers can render
6653
- * grouping intent that `expand_auto_discover` would otherwise flatten out
6654
- * of `zones[]`.
6763
+ * the architecture boundary zones, rules, and the user's pre-expansion
6764
+ * `autoDiscover` logical groups so consumers can render grouping intent that
6765
+ * expansion would otherwise flatten out of `zones[]`.
6655
6766
  */
6656
6767
  export interface ListBoundariesOutput {
6657
6768
  boundaries: BoundariesListing
@@ -6688,10 +6799,10 @@ from: string
6688
6799
  allow: string[]
6689
6800
  }
6690
6801
  /**
6691
- * A pre-expansion `autoDiscover` logical group surfaced for observability
6692
- * (issue #373). Captured during `expand_auto_discover` so consumers can
6693
- * see the user-authored parent name and grouping intent after expansion
6694
- * would otherwise flatten it out of [`BoundariesListing::zones`].
6802
+ * A pre-expansion `autoDiscover` logical group surfaced for observability.
6803
+ * Captured during expansion so consumers can see the user-authored parent
6804
+ * name and grouping intent after expansion would otherwise flatten it out of
6805
+ * [`BoundariesListing::zones`].
6695
6806
  */
6696
6807
  export interface BoundariesListLogicalGroup {
6697
6808
  name: string
@@ -6779,7 +6890,7 @@ elapsed_ms: ElapsedMs
6779
6890
  /**
6780
6891
  * Functions and synthetic template entries exceeding complexity
6781
6892
  * thresholds, sorted by the --sort criteria. Each entry wraps its
6782
- * inner [`ComplexityViolation`] payload (flattened on the wire) with
6893
+ * inner `ComplexityViolation` payload (flattened on the wire) with
6783
6894
  * the typed `actions` list and an optional audit-mode `introduced`
6784
6895
  * flag.
6785
6896
  */
@@ -6824,7 +6935,7 @@ prop_drilling_chains?: PropDrillingChainFinding[]
6824
6935
  /**
6825
6936
  * Hotspot entries combining git churn with complexity. Only present when
6826
6937
  * --hotspots is used. Sorted by score descending (highest risk first).
6827
- * Each entry wraps its inner [`HotspotEntry`] payload (flattened on the
6938
+ * Each entry wraps its inner `HotspotEntry` payload (flattened on the
6828
6939
  * wire) with a typed `actions` list.
6829
6940
  */
6830
6941
  hotspots?: HotspotFinding[]
@@ -6849,7 +6960,7 @@ large_functions?: LargeFunctionEntry[]
6849
6960
  /**
6850
6961
  * Ranked refactoring recommendations. Only present when --targets is used.
6851
6962
  * Sorted by efficiency (priority/effort) descending. Each entry wraps
6852
- * its inner [`RefactoringTarget`] payload (flattened on the wire) with
6963
+ * its inner `RefactoringTarget` payload (flattened on the wire) with
6853
6964
  * a typed `actions` list.
6854
6965
  */
6855
6966
  targets?: RefactoringTargetFinding[]
@@ -6886,7 +6997,7 @@ _meta?: (Meta | null)
6886
6997
  workspace_diagnostics?: WorkspaceDiagnostic[]
6887
6998
  /**
6888
6999
  * Read-only follow-up commands computed from this run's findings. See
6889
- * [`CheckOutput::next_steps`] for the contract.
7000
+ * `CheckOutput::next_steps` for the contract.
6890
7001
  */
6891
7002
  next_steps?: NextStep[]
6892
7003
  }
@@ -6901,7 +7012,7 @@ next_steps?: NextStep[]
6901
7012
  * files in the group, so they answer "what is the health of workspace X" in
6902
7013
  * a single invocation. `files_analyzed` and `functions_above_threshold`
6903
7014
  * summarise the subset for parity with the project-level
6904
- * [`crate::health_types::HealthSummary`].
7015
+ * project-level health summary.
6905
7016
  */
6906
7017
  export interface HealthGroup {
6907
7018
  /**
@@ -6948,7 +7059,7 @@ health_score?: (HealthScore | null)
6948
7059
  /**
6949
7060
  * Findings restricted to files in this group. Each entry is the typed
6950
7061
  * [`HealthFinding`] wrapper around a
6951
- * [`ComplexityViolation`](crate::health_types::ComplexityViolation)
7062
+ * `ComplexityViolation`
6952
7063
  * payload.
6953
7064
  */
6954
7065
  findings?: HealthFinding[]
@@ -6959,7 +7070,7 @@ file_scores?: FileHealthScore[]
6959
7070
  /**
6960
7071
  * Hotspots restricted to files in this group. Each entry is the typed
6961
7072
  * [`HotspotFinding`] wrapper around a
6962
- * [`HotspotEntry`](crate::health_types::HotspotEntry) payload.
7073
+ * `HotspotEntry` payload.
6963
7074
  */
6964
7075
  hotspots?: HotspotFinding[]
6965
7076
  /**
@@ -6969,7 +7080,7 @@ large_functions?: LargeFunctionEntry[]
6969
7080
  /**
6970
7081
  * Refactoring targets in files belonging to this group. Each entry is
6971
7082
  * the typed [`RefactoringTargetFinding`] wrapper around a
6972
- * [`RefactoringTarget`](crate::health_types::RefactoringTarget)
7083
+ * `RefactoringTarget`
6973
7084
  * payload.
6974
7085
  */
6975
7086
  targets?: RefactoringTargetFinding[]
@@ -6977,21 +7088,17 @@ targets?: RefactoringTargetFinding[]
6977
7088
  * Auditable breadcrumb recording why `suppress-line` action hints
6978
7089
  * were omitted from this group's findings. Mirrors the project-level
6979
7090
  * `HealthReport.actions_meta`; populated at construction time when the
6980
- * per-group [`HealthActionContext`](crate::health_types::HealthActionContext)
7091
+ * per-group `HealthActionContext`
6981
7092
  * suppresses inline hints.
6982
7093
  */
6983
7094
  actions_meta?: (HealthActionsMeta | null)
6984
7095
  }
6985
7096
  /**
6986
- * Wire-shape payload for `fallow dupes --format json` (the body that
6987
- * flattens into [`crate::output_envelope::DupesOutput`] and is also
6988
- * emitted under the `dupes` / `duplication` key inside the combined and
6989
- * audit envelopes).
7097
+ * Envelope emitted by `fallow dupes --format json`.
6990
7098
  *
6991
- * Mirrors [`DuplicationReport`] field-for-field, except `clone_groups`
6992
- * and `clone_families` carry the typed wrapper envelopes instead of bare
6993
- * findings, so the schema (and any TS / agent consumer) sees the typed
6994
- * `actions[]` natively.
7099
+ * `Report` and `Group` are generic so the envelope can live in
7100
+ * `fallow-output` while duplication report wrappers and grouped output
7101
+ * internals continue to migrate out of CLI/API-specific crates.
6995
7102
  */
6996
7103
  export interface DupesOutput {
6997
7104
  schema_version: SchemaVersion
@@ -7003,8 +7110,8 @@ elapsed_ms: ElapsedMs
7003
7110
  clone_groups: CloneGroupFinding[]
7004
7111
  /**
7005
7112
  * Clone families, each wrapped with typed actions. Inner `groups`
7006
- * inside each [`CloneFamilyFinding`] are themselves wrapped as
7007
- * [`CloneGroupFinding`] entries carrying their own `actions[]` (and
7113
+ * inside each `CloneFamilyFinding` are themselves wrapped as
7114
+ * `CloneGroupFinding` entries carrying their own `actions[]` (and
7008
7115
  * optional audit-mode `introduced` flag), so JSON-Schema strict
7009
7116
  * consumers and TS consumers reading `clone_families[].groups[]` see
7010
7117
  * the same shape as the top-level `clone_groups[]` array (preserves
@@ -7026,7 +7133,7 @@ groups?: (DuplicationGroup[] | null)
7026
7133
  _meta?: (Meta | null)
7027
7134
  /**
7028
7135
  * Workspace-discovery diagnostics surfaced during config load
7029
- * (issue #473). See [`CheckOutput::workspace_diagnostics`] for the full
7136
+ * (issue #473). See `CheckOutput::workspace_diagnostics` for the full
7030
7137
  * contract; the same list is repeated on each top-level command's
7031
7138
  * envelope so single-command consumers see it without having to look at
7032
7139
  * a separate top-level field.
@@ -7034,7 +7141,7 @@ _meta?: (Meta | null)
7034
7141
  workspace_diagnostics?: WorkspaceDiagnostic[]
7035
7142
  /**
7036
7143
  * Read-only follow-up commands computed from this run's findings. See
7037
- * [`CheckOutput::next_steps`] for the contract.
7144
+ * `CheckOutput::next_steps` for the contract.
7038
7145
  */
7039
7146
  next_steps?: NextStep[]
7040
7147
  }
@@ -7067,7 +7174,7 @@ clone_families: CloneFamilyFinding[]
7067
7174
  * Wire-shape envelope for an [`AttributedCloneGroup`] finding (per-bucket
7068
7175
  * duplication attribution emitted under `fallow dupes --group-by`).
7069
7176
  * Flattens the attributed group and carries the same typed
7070
- * `CloneGroupAction` array as [`CloneGroupFinding`]; no `introduced`
7177
+ * `CloneGroupAction` array as `CloneGroupFinding`; no `introduced`
7071
7178
  * field because `fallow audit` does not run on grouped output.
7072
7179
  */
7073
7180
  export interface AttributedCloneGroupFinding {
@@ -7076,7 +7183,13 @@ export interface AttributedCloneGroupFinding {
7076
7183
  * this clone group. Ties broken alphabetically (smallest key wins).
7077
7184
  */
7078
7185
  primary_owner: string
7186
+ /**
7187
+ * Number of tokens in the clone group.
7188
+ */
7079
7189
  token_count: number
7190
+ /**
7191
+ * Number of source lines in the clone group.
7192
+ */
7080
7193
  line_count: number
7081
7194
  /**
7082
7195
  * Each instance carries its own `owner` field alongside the standard
@@ -7486,7 +7599,7 @@ thin_wrappers?: ThinWrapperFinding[]
7486
7599
  duplicate_prop_shapes?: DuplicatePropShapeFinding[]
7487
7600
  }
7488
7601
  /**
7489
- * The rendered impact report, derived purely from the store (no analysis run).
7602
+ * The rendered impact report, derived purely from the store.
7490
7603
  */
7491
7604
  export interface ImpactReport {
7492
7605
  schema_version: ImpactReportSchemaVersion
@@ -7582,18 +7695,24 @@ duplication: number
7582
7695
  export interface TrendSummary {
7583
7696
  direction: ImpactTrendDirection
7584
7697
  /**
7585
- * Signed delta in total issues (current minus previous).
7698
+ * Signed delta in total issues, current minus previous.
7586
7699
  */
7587
7700
  total_delta: number
7588
7701
  previous_total: number
7589
7702
  current_total: number
7590
7703
  }
7704
+ /**
7705
+ * A commit-gate containment event recorded by `fallow impact`.
7706
+ */
7591
7707
  export interface ContainmentEvent {
7592
7708
  blocked_at: string
7593
7709
  cleared_at: string
7594
7710
  git_sha?: (string | null)
7595
7711
  blocked_counts: ImpactCounts
7596
7712
  }
7713
+ /**
7714
+ * A resolved or suppressed finding attribution event.
7715
+ */
7597
7716
  export interface ResolutionEvent {
7598
7717
  kind: string
7599
7718
  path: string
@@ -7602,7 +7721,7 @@ git_sha?: (string | null)
7602
7721
  timestamp: string
7603
7722
  }
7604
7723
  /**
7605
- * The cross-repo aggregate report (`fallow impact --all --format json`).
7724
+ * The cross-repo aggregate report, `fallow impact --all --format json`.
7606
7725
  */
7607
7726
  export interface CrossRepoImpactReport {
7608
7727
  schema_version: CrossRepoImpactSchemaVersion
@@ -8235,17 +8354,8 @@ top_files_limit: number
8235
8354
  * One sampled unresolved-callee row.
8236
8355
  */
8237
8356
  export interface SecurityUnresolvedCalleeSample {
8238
- /**
8239
- * Project-relative source path.
8240
- */
8241
8357
  path: string
8242
- /**
8243
- * 1-based source line.
8244
- */
8245
8358
  line: number
8246
- /**
8247
- * 0-based byte column.
8248
- */
8249
8359
  col: number
8250
8360
  reason: SkippedSecurityCalleeReason
8251
8361
  expression_kind: SkippedSecurityCalleeExpressionKind
@@ -8254,9 +8364,6 @@ expression_kind: SkippedSecurityCalleeExpressionKind
8254
8364
  * Count of unresolved callees in one file.
8255
8365
  */
8256
8366
  export interface SecurityUnresolvedCalleeTopFile {
8257
- /**
8258
- * Project-relative source path.
8259
- */
8260
8367
  path: string
8261
8368
  /**
8262
8369
  * Number of unresolved callees in this file.
@@ -8397,13 +8504,7 @@ export interface SecuritySurvivor {
8397
8504
  */
8398
8505
  finding_id: string
8399
8506
  verdict: SecurityVerifierVerdictStatus
8400
- /**
8401
- * Short verifier reason.
8402
- */
8403
8507
  reason?: (string | null)
8404
- /**
8405
- * Short verifier rationale.
8406
- */
8407
8508
  rationale?: (string | null)
8408
8509
  /**
8409
8510
  * Optional verifier-provided confidence or review priority.
@@ -8463,9 +8564,6 @@ suggestion: string
8463
8564
  * One file inside a blind-spot group.
8464
8565
  */
8465
8566
  export interface SecurityBlindSpotFile {
8466
- /**
8467
- * Project-relative source path.
8468
- */
8469
8567
  path: string
8470
8568
  /**
8471
8569
  * Count in the bounded diagnostic sample.
@@ -8485,10 +8583,13 @@ dupes?: (DupesReportPayload | null)
8485
8583
  health?: (HealthReport | null)
8486
8584
  /**
8487
8585
  * Read-only follow-up commands aggregated across the combined run's
8488
- * findings. See [`CheckOutput::next_steps`] for the contract.
8586
+ * findings. See `CheckOutput::next_steps` for the contract.
8489
8587
  */
8490
8588
  next_steps?: NextStep[]
8491
8589
  }
8590
+ /**
8591
+ * Optional `_meta` block for [`CombinedOutput`].
8592
+ */
8492
8593
  export interface CombinedMeta {
8493
8594
  check?: (Meta | null)
8494
8595
  dupes?: (Meta | null)
@@ -8786,7 +8887,7 @@ export interface RoutingFacts {
8786
8887
  units: RoutingUnit[]
8787
8888
  }
8788
8889
  /**
8789
- * One routed unit (a changed file) with its experts and bus-factor flag.
8890
+ * One routed unit with its experts and bus-factor flag.
8790
8891
  */
8791
8892
  export interface RoutingUnit {
8792
8893
  /**
@@ -8810,11 +8911,11 @@ bus_factor_one?: boolean
8810
8911
  */
8811
8912
  export interface DecisionSurface {
8812
8913
  /**
8813
- * Up to `cap` ranked decisions, highest consequence first.
8914
+ * Ranked decisions, highest consequence first.
8814
8915
  */
8815
8916
  decisions: Decision[]
8816
8917
  /**
8817
- * Present when more than `cap` decisions were extracted.
8918
+ * Present when more than the cap were extracted.
8818
8919
  */
8819
8920
  truncated?: (TruncationNote | null)
8820
8921
  /**
@@ -8840,7 +8941,7 @@ category: DecisionCategory
8840
8941
  */
8841
8942
  question: string
8842
8943
  /**
8843
- * Root-relative file the decision is anchored at (for suppression + routing).
8944
+ * Root-relative file the decision is anchored at.
8844
8945
  */
8845
8946
  anchor_file: string
8846
8947
  /**
@@ -8848,7 +8949,7 @@ anchor_file: string
8848
8949
  */
8849
8950
  anchor_line: number
8850
8951
  /**
8851
- * The raw fallow-emitted candidate key the `signal_id` hashes (the evidence).
8952
+ * The raw fallow-emitted candidate key the `signal_id` hashes.
8852
8953
  */
8853
8954
  signal_key: string
8854
8955
  /**
@@ -8873,7 +8974,7 @@ consequence: number
8873
8974
  */
8874
8975
  expert: string[]
8875
8976
  /**
8876
- * Whether the anchor file's only qualified owner is one person (bus-factor-1).
8977
+ * Whether the anchor file's only qualified owner is one person.
8877
8978
  */
8878
8979
  bus_factor_one?: boolean
8879
8980
  /**
@@ -8894,7 +8995,7 @@ internal_consumer_count: number
8894
8995
  tradeoff: string
8895
8996
  }
8896
8997
  /**
8897
- * A note for the decisions collapsed below the cap.
8998
+ * A note for decisions collapsed below the cap.
8898
8999
  */
8899
9000
  export interface TruncationNote {
8900
9001
  /**
@@ -8955,7 +9056,7 @@ export interface ReviewDirection {
8955
9056
  */
8956
9057
  order: string[]
8957
9058
  /**
8958
- * The coherent review units, in `order`.
9059
+ * Coherent review units, in `order`.
8959
9060
  */
8960
9061
  units: DirectionUnit[]
8961
9062
  }
@@ -8986,7 +9087,7 @@ scoring_budget: number
8986
9087
  */
8987
9088
  out_of_diff: string[]
8988
9089
  /**
8989
- * The routed expert(s) to ask, from ownership routing.
9090
+ * Routed expert(s), when ownership signals are available.
8990
9091
  */
8991
9092
  expert: string[]
8992
9093
  }
@@ -9041,7 +9142,7 @@ judgment_shape: string
9041
9142
  */
9042
9143
  echo_field: string
9043
9144
  /**
9044
- * The constant naming the anti-hallucination rule.
9145
+ * The anchoring rule name.
9045
9146
  */
9046
9147
  anchoring_rule: string
9047
9148
  }
@@ -9114,11 +9215,11 @@ change_anchor: string
9114
9215
  */
9115
9216
  anchor_kind: string
9116
9217
  /**
9117
- * The agent's framing, FENCED: this is non-deterministic agent prose.
9218
+ * The agent's fenced free-text framing.
9118
9219
  */
9119
9220
  agent_framing: string
9120
9221
  /**
9121
- * The agent's optional concern category (advisory).
9222
+ * The agent's optional concern category.
9122
9223
  */
9123
9224
  concern?: (string | null)
9124
9225
  /**
@@ -9159,6 +9260,15 @@ categories: string[]
9159
9260
  severity: CodeClimateSeverity
9160
9261
  fingerprint: string
9161
9262
  location: CodeClimateLocation
9263
+ /**
9264
+ * Optional owner attribution used by grouped dead-code output.
9265
+ */
9266
+ owner?: (string | null)
9267
+ /**
9268
+ * Optional grouping attribution used by grouped health and duplication
9269
+ * output.
9270
+ */
9271
+ group?: (string | null)
9162
9272
  }
9163
9273
  /**
9164
9274
  * Location block inside [`CodeClimateIssue::location`].