fallow 2.101.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.
@@ -85,6 +85,12 @@ kind: "security-blind-spots"
85
85
  kind: "dead-code"
86
86
  }) | (CombinedOutput & {
87
87
  kind: "combined"
88
+ }) | (ReviewBriefOutput & {
89
+ kind: "audit-brief"
90
+ }) | (WalkthroughGuide & {
91
+ kind: "review-walkthrough-guide"
92
+ }) | (WalkthroughValidation & {
93
+ kind: "review-walkthrough-validation"
88
94
  }))
89
95
  /**
90
96
  * Schema version for this output format (independent of tool version). Bump
@@ -113,6 +119,9 @@ export type SchemaVersion = 7
113
119
  * a bare string (e.g. `"2.74.0"`).
114
120
  */
115
121
  export type ToolVersion = string
122
+ /**
123
+ * Audit command singleton carried by [`AuditOutput`].
124
+ */
116
125
  export type AuditCommand = "audit"
117
126
  /**
118
127
  * Verdict for the audit command.
@@ -444,7 +453,8 @@ export type UntestedFileActionType = ("add-tests" | "suppress-file")
444
453
  */
445
454
  export type UntestedExportActionType = ("add-test-import" | "suppress-file")
446
455
  /**
447
- * 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.
448
458
  */
449
459
  export type ChurnTrend = ("accelerating" | "stable" | "cooling")
450
460
  export type ContributorIdentifierFormat = ("raw" | "handle" | "anonymized" | "hash")
@@ -763,6 +773,44 @@ export type SecurityVerifierVerdictStatus = ("survivor" | "dismissed" | "needs-h
763
773
  * The `fallow security blind-spots --format json` schema version.
764
774
  */
765
775
  export type SecurityBlindSpotsSchemaVersion = "1"
776
+ /**
777
+ * Independently-versioned wire-version newtype for the brief envelope.
778
+ * Serializes as the integer `REVIEW_BRIEF_SCHEMA_VERSION`.
779
+ */
780
+ export type ReviewBriefSchemaVersion = number
781
+ /**
782
+ * Coarse risk classification for a changeset, a pure function of the change
783
+ * size (file count plus, once threaded, net lines).
784
+ */
785
+ export type RiskClass = ("low" | "medium" | "high")
786
+ /**
787
+ * Suggested reviewer effort, a pure function of [`RiskClass`].
788
+ */
789
+ export type ReviewEffort = ("glance" | "review" | "deep_dive")
790
+ /**
791
+ * The focus label for a review unit. EXACTLY two variants: `Skip` is NOT
792
+ * representable, so the type system is the guarantee that free mode never emits
793
+ * a `skip` label (safe explicit-skip is paid, runtime-backed only). Mirrors
794
+ * the decision surface's "cut category not representable" structural posture.
795
+ */
796
+ export type FocusLabel = ("review-here" | "not-prioritized")
797
+ /**
798
+ * A per-unit confidence flag. The EXACT panel-decided strings: a dynamically-
799
+ * wired or re-export-heavy unit carries one so its static-reachability signal is
800
+ * not trusted as complete (the anti-silent-de-prioritization guard). The flag
801
+ * NEVER lowers the score; it is advisory provenance.
802
+ */
803
+ export type ConfidenceFlag = ("dynamic-dispatch" | "re-export-indirection")
804
+ /**
805
+ * The category of a single weakening signal.
806
+ */
807
+ export type WeakeningKind = ("test-weakened" | "threshold-lowered" | "suppression-added" | "security-check-removed")
808
+ /**
809
+ * The exactly-three shippable decision categories (the SOLID-3). No cut category
810
+ * (abstraction / deletion / convention / irreversibility) is representable: this
811
+ * enum is the structural guarantee that confirmed-noise categories never ship.
812
+ */
813
+ export type DecisionCategory = ("coupling-boundary" | "public-api-contract" | "dependency")
766
814
  /**
767
815
  * Discriminator value for [`CodeClimateIssue::kind`].
768
816
  */
@@ -807,7 +855,7 @@ duplication?: (DupesReportPayload | null)
807
855
  complexity?: (HealthReport | null)
808
856
  /**
809
857
  * Read-only follow-up commands computed from this run's findings. See
810
- * [`CheckOutput::next_steps`] for the contract.
858
+ * `CheckOutput::next_steps` for the contract.
811
859
  */
812
860
  next_steps?: NextStep[]
813
861
  }
@@ -2882,11 +2930,15 @@ export interface UnrenderedComponentFinding {
2882
2930
  */
2883
2931
  path: string
2884
2932
  /**
2885
- * The component name (the `.vue`/`.svelte` file stem, PascalCase).
2933
+ * The component name. For `"vue"` / `"svelte"` / `"astro"` this is the SFC
2934
+ * file stem (PascalCase); for `"angular"` it is the component class name; for
2935
+ * `"lit"` it is the registered custom-element TAG (e.g. `x-foo`), not a file
2936
+ * stem. Use `path` to anchor the file across all frameworks.
2886
2937
  */
2887
2938
  component_name: string
2888
2939
  /**
2889
- * Which framework this component belongs to: `"vue"` or `"svelte"`.
2940
+ * Which framework this component belongs to: `"vue"`, `"svelte"`, `"astro"`,
2941
+ * `"angular"`, or `"lit"`.
2890
2942
  */
2891
2943
  framework: string
2892
2944
  /**
@@ -3563,7 +3615,7 @@ reason: string
3563
3615
  }
3564
3616
  /**
3565
3617
  * Wire-shape payload for `fallow dupes --format json` (the body that
3566
- * flattens into [`crate::output_envelope::DupesOutput`] and is also
3618
+ * flattens into the `DupesOutput` envelope and is also
3567
3619
  * emitted under the `dupes` / `duplication` key inside the combined and
3568
3620
  * audit envelopes).
3569
3621
  *
@@ -3579,8 +3631,8 @@ export interface DupesReportPayload {
3579
3631
  clone_groups: CloneGroupFinding[]
3580
3632
  /**
3581
3633
  * Clone families, each wrapped with typed actions. Inner `groups`
3582
- * inside each [`CloneFamilyFinding`] are themselves wrapped as
3583
- * [`CloneGroupFinding`] entries carrying their own `actions[]` (and
3634
+ * inside each `CloneFamilyFinding` are themselves wrapped as
3635
+ * `CloneGroupFinding` entries carrying their own `actions[]` (and
3584
3636
  * optional audit-mode `introduced` flag), so JSON-Schema strict
3585
3637
  * consumers and TS consumers reading `clone_families[].groups[]` see
3586
3638
  * the same shape as the top-level `clone_groups[]` array (preserves
@@ -3670,8 +3722,8 @@ end_col: number
3670
3722
  fragment: string
3671
3723
  }
3672
3724
  /**
3673
- * Per-action wire shape attached to each [`CloneGroupFinding`] and
3674
- * [`AttributedCloneGroupFinding`]. Mirrors the action types previously
3725
+ * Per-action wire shape attached to each `CloneGroupFinding` and
3726
+ * `AttributedCloneGroupFinding`. Mirrors the action types previously
3675
3727
  * emitted by `inject_dupes_actions::build_clone_group_actions` in
3676
3728
  * `crates/cli/src/report/json.rs`: `extract-shared` plus `suppress-line`.
3677
3729
  */
@@ -3700,7 +3752,7 @@ comment?: (string | null)
3700
3752
  * Unlike most `*Finding` wrappers this one is NOT `#[serde(flatten)]` over
3701
3753
  * the bare [`CloneFamily`], because the family's nested
3702
3754
  * `groups: Vec<CloneGroup>` field needs to carry the typed
3703
- * [`CloneGroupFinding`] wrapper too (so every nested clone group gets its
3755
+ * `CloneGroupFinding` wrapper too (so every nested clone group gets its
3704
3756
  * own `actions[]` array, matching the legacy post-pass behavior; see issue
3705
3757
  * #393 regression test). The wire shape stays byte-identical to the
3706
3758
  * previous post-pass output. No `introduced` field because `fallow audit`
@@ -3708,7 +3760,7 @@ comment?: (string | null)
3708
3760
  */
3709
3761
  export interface CloneFamilyFinding {
3710
3762
  /**
3711
- * The files involved in this family (sorted for stable output).
3763
+ * The files involved in this family.
3712
3764
  */
3713
3765
  files: string[]
3714
3766
  /**
@@ -3731,7 +3783,7 @@ total_duplicated_tokens: number
3731
3783
  suggestions: RefactoringSuggestion[]
3732
3784
  /**
3733
3785
  * Suggested next steps: an `extract-shared` primary, one
3734
- * `apply-suggestion` per [`RefactoringSuggestion`] on the family, and
3786
+ * `apply-suggestion` per `RefactoringSuggestion` on the family, and
3735
3787
  * a trailing `suppress-line`. Always emitted (possibly empty for
3736
3788
  * forward-compat).
3737
3789
  */
@@ -3752,10 +3804,10 @@ description: string
3752
3804
  estimated_savings: number
3753
3805
  }
3754
3806
  /**
3755
- * Per-action wire shape attached to each [`CloneFamilyFinding`]. Mirrors
3807
+ * Per-action wire shape attached to each `CloneFamilyFinding`. Mirrors
3756
3808
  * the action types previously emitted by
3757
3809
  * `build_clone_family_actions`: `extract-shared`, one `apply-suggestion`
3758
- * per [`RefactoringSuggestion`] on the family, and a trailing
3810
+ * per `RefactoringSuggestion` on the family, and a trailing
3759
3811
  * `suppress-line`.
3760
3812
  */
3761
3813
  export interface CloneFamilyAction {
@@ -3864,7 +3916,7 @@ export interface HealthReport {
3864
3916
  /**
3865
3917
  * Functions and synthetic template entries exceeding complexity
3866
3918
  * thresholds, sorted by the --sort criteria. Each entry wraps its
3867
- * inner [`ComplexityViolation`] payload (flattened on the wire) with
3919
+ * inner `ComplexityViolation` payload (flattened on the wire) with
3868
3920
  * the typed `actions` list and an optional audit-mode `introduced`
3869
3921
  * flag.
3870
3922
  */
@@ -3909,7 +3961,7 @@ prop_drilling_chains?: PropDrillingChainFinding[]
3909
3961
  /**
3910
3962
  * Hotspot entries combining git churn with complexity. Only present when
3911
3963
  * --hotspots is used. Sorted by score descending (highest risk first).
3912
- * Each entry wraps its inner [`HotspotEntry`] payload (flattened on the
3964
+ * Each entry wraps its inner `HotspotEntry` payload (flattened on the
3913
3965
  * wire) with a typed `actions` list.
3914
3966
  */
3915
3967
  hotspots?: HotspotFinding[]
@@ -3934,7 +3986,7 @@ large_functions?: LargeFunctionEntry[]
3934
3986
  /**
3935
3987
  * Ranked refactoring recommendations. Only present when --targets is used.
3936
3988
  * Sorted by efficiency (priority/effort) descending. Each entry wraps
3937
- * its inner [`RefactoringTarget`] payload (flattened on the wire) with
3989
+ * its inner `RefactoringTarget` payload (flattened on the wire) with
3938
3990
  * a typed `actions` list.
3939
3991
  */
3940
3992
  targets?: RefactoringTargetFinding[]
@@ -4141,7 +4193,7 @@ max_crap: number
4141
4193
  * `comment` plus `placement`, and the coverage-leaning actions
4142
4194
  * (`add-tests`, `increase-coverage`) carry only `note`.
4143
4195
  *
4144
- * [`ComplexityViolation`]: ../../fallow-cli/src/health_types/scores.rs
4196
+ * [`ComplexityViolation`]: ../../fallow-output/src/health_scores.rs
4145
4197
  */
4146
4198
  export interface HealthFindingAction {
4147
4199
  type: HealthFindingActionType
@@ -4239,7 +4291,7 @@ cognitive: number
4239
4291
  crap?: (number | null)
4240
4292
  }
4241
4293
  /**
4242
- * 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.
4243
4295
  *
4244
4296
  * Metrics are `Option` when the data source was not available in the current run
4245
4297
  * (e.g., `duplication_pct` is `None` unless the duplication pipeline was run,
@@ -4280,7 +4332,7 @@ hotspot_count?: (number | null)
4280
4332
  */
4281
4333
  hotspot_top_pct_count?: (number | null)
4282
4334
  /**
4283
- * Average maintainability index across all scored files (0100).
4335
+ * Average maintainability index across all scored files (0-100).
4284
4336
  */
4285
4337
  maintainability_avg?: (number | null)
4286
4338
  /**
@@ -4568,7 +4620,7 @@ path: string
4568
4620
  value_export_count: number
4569
4621
  /**
4570
4622
  * Suggested next steps: an `add-tests` primary and a `suppress-file`
4571
- * secondary. Always emitted (possibly empty for forward-compat).
4623
+ * secondary. Always emitted for the current wire contract.
4572
4624
  */
4573
4625
  actions: UntestedFileAction[]
4574
4626
  }
@@ -4582,7 +4634,7 @@ actions: UntestedFileAction[]
4582
4634
  * struct shape; the field that is populated (`note` for `add-tests`,
4583
4635
  * `comment` for `suppress-file`) depends on the `kind`.
4584
4636
  *
4585
- * [`UntestedFile`]: ../../fallow-cli/src/health_types/coverage.rs
4637
+ * [`UntestedFile`]: ../../fallow-output/src/health_coverage_gaps.rs
4586
4638
  */
4587
4639
  export interface UntestedFileAction {
4588
4640
  type: UntestedFileActionType
@@ -4645,7 +4697,7 @@ actions: UntestedExportAction[]
4645
4697
  * `add-test-import` reflects that a test-reachable reference chain, not
4646
4698
  * just any test coverage, is what closes the gap.
4647
4699
  *
4648
- * [`UntestedExport`]: ../../fallow-cli/src/health_types/coverage.rs
4700
+ * [`UntestedExport`]: ../../fallow-output/src/health_coverage_gaps.rs
4649
4701
  */
4650
4702
  export interface UntestedExportAction {
4651
4703
  type: UntestedExportActionType
@@ -4736,7 +4788,7 @@ commits: number
4736
4788
  * `ownership-drift`) are appended only when `--ownership` is active AND
4737
4789
  * the corresponding signal fires for the hotspot.
4738
4790
  *
4739
- * [`HotspotEntry`]: ../../fallow-cli/src/health_types/scores.rs
4791
+ * [`HotspotEntry`]: ../../fallow-output/src/health_scores.rs
4740
4792
  */
4741
4793
  export interface HotspotAction {
4742
4794
  type: HotspotActionType
@@ -4822,6 +4874,27 @@ watermark?: (RuntimeCoverageWatermark | null)
4822
4874
  * Non-fatal merge or coverage diagnostics. Omitted when empty.
4823
4875
  */
4824
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
4825
4898
  }
4826
4899
  /**
4827
4900
  * Summary block mirroring `fallow_cov_protocol::Summary` (0.3 shape).
@@ -4862,7 +4935,7 @@ coverage_percent: number
4862
4935
  trace_count: number
4863
4936
  /**
4864
4937
  * Days of observation covered by the supplied dump (Phase 2 local analysis
4865
- * emits 0 , set by the beacon/cloud in Phase 3+).
4938
+ * emits 0, set by the beacon/cloud in Phase 3+).
4866
4939
  */
4867
4940
  period_days: number
4868
4941
  /**
@@ -4957,6 +5030,13 @@ evidence: RuntimeCoverageEvidence
4957
5030
  * Suggested actions for this finding. Omitted when empty.
4958
5031
  */
4959
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)
4960
5040
  }
4961
5041
  /**
4962
5042
  * Supporting evidence for a finding (mirrors `fallow_cov_protocol::Evidence`).
@@ -5009,6 +5089,48 @@ description: string
5009
5089
  */
5010
5090
  auto_fixable: boolean
5011
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
+ }
5012
5134
  export interface RuntimeCoverageHotPath {
5013
5135
  /**
5014
5136
  * Stable content-hash ID of the form `fallow:hot:<hash>`.
@@ -5146,6 +5268,44 @@ code: string
5146
5268
  */
5147
5269
  message: string
5148
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
+ }
5149
5309
  /**
5150
5310
  * Combined coverage, runtime, complexity, and change-scope verdicts.
5151
5311
  */
@@ -5417,7 +5577,7 @@ fingerprint: string
5417
5577
  * the target's `evidence.complex_functions` back to the matching
5418
5578
  * `ComplexityViolation` and read placement from THAT action instead.
5419
5579
  *
5420
- * [`RefactoringTarget`]: ../../fallow-cli/src/health_types/targets.rs
5580
+ * [`RefactoringTarget`]: ../../fallow-output/src/health_targets.rs
5421
5581
  */
5422
5582
  export interface RefactoringTargetAction {
5423
5583
  type: RefactoringTargetActionType
@@ -5435,7 +5595,7 @@ description: string
5435
5595
  /**
5436
5596
  * Recommendation category for `apply-refactoring` actions. Mirrors
5437
5597
  * the parent target's
5438
- * [`category`](../../fallow-cli/src/health_types/targets.rs.html)
5598
+ * [`category`](../../fallow-output/src/health_targets.rs.html)
5439
5599
  * field so consumers can route on the action alone.
5440
5600
  */
5441
5601
  category?: (string | null)
@@ -5519,11 +5679,11 @@ snapshot_schema_version?: (number | null)
5519
5679
  */
5520
5680
  export interface TrendMetric {
5521
5681
  /**
5522
- * Metric identifier (e.g., `"score"`, `"dead_file_pct"`).
5682
+ * Metric identifier, e.g. `"score"` or `"dead_file_pct"`.
5523
5683
  */
5524
5684
  name: string
5525
5685
  /**
5526
- * Human-readable label (e.g., `"Health Score"`, `"Dead Files"`).
5686
+ * Human-readable label, e.g. `"Health Score"` or `"Dead Files"`.
5527
5687
  */
5528
5688
  label: string
5529
5689
  /**
@@ -5535,12 +5695,12 @@ previous: number
5535
5695
  */
5536
5696
  current: number
5537
5697
  /**
5538
- * Absolute change (current previous).
5698
+ * Absolute change (current - previous).
5539
5699
  */
5540
5700
  delta: number
5541
5701
  direction: TrendDirection
5542
5702
  /**
5543
- * Unit for display (e.g., `"%"`, `""`, `"pts"`).
5703
+ * Unit for display, e.g. `"%"`, `""`, or `"pts"`.
5544
5704
  */
5545
5705
  unit: string
5546
5706
  /**
@@ -5557,11 +5717,11 @@ current_count?: (TrendCount | null)
5557
5717
  */
5558
5718
  export interface TrendCount {
5559
5719
  /**
5560
- * The numerator (e.g., dead files count).
5720
+ * The numerator, e.g. dead files count.
5561
5721
  */
5562
5722
  value: number
5563
5723
  /**
5564
- * The denominator (e.g., total files).
5724
+ * The denominator, e.g. total files.
5565
5725
  */
5566
5726
  total: number
5567
5727
  }
@@ -5569,10 +5729,10 @@ total: number
5569
5729
  * Auditable breadcrumb recording when health-finding `suppress-line`
5570
5730
  * action hints were omitted from the report.
5571
5731
  *
5572
- * Set at construction time on [`HealthReport::actions_meta`] (and on
5573
- * each [`HealthGroup::actions_meta`](crate::health_types::HealthGroup)
5732
+ * Set at construction time on `HealthReport::actions_meta` (and on
5733
+ * each `HealthGroup::actions_meta`
5574
5734
  * when grouped) by the report builder, derived from the active
5575
- * [`HealthActionContext`]. Lets consumers see "where did the
5735
+ * `HealthActionContext`. Lets consumers see "where did the
5576
5736
  * suppress-line hints go?" without having to grep the config or CLI
5577
5737
  * history.
5578
5738
  *
@@ -5584,8 +5744,8 @@ total: number
5584
5744
  */
5585
5745
  export interface HealthActionsMeta {
5586
5746
  /**
5587
- * Always `true` when the breadcrumb is emitted. Absent from the wire
5588
- * when no suppression occurred.
5747
+ * Always `true` when the breadcrumb is emitted. Absent from the wire when
5748
+ * no suppression occurred.
5589
5749
  */
5590
5750
  suppression_hints_omitted: boolean
5591
5751
  /**
@@ -6453,6 +6613,14 @@ dead_code: InspectEvidenceSection
6453
6613
  duplication: InspectEvidenceSection
6454
6614
  complexity: InspectEvidenceSection
6455
6615
  security: InspectEvidenceSection
6616
+ impact_closure: InspectEvidenceSection
6617
+ /**
6618
+ * OPT-IN symbol-level call chain. Present only when `--symbol-chain` was
6619
+ * requested AND the target is a SYMBOL (best-effort, syntactic, OFF the
6620
+ * ranked path). `None` (omitted) by default: symbol-level chains are
6621
+ * best-effort and not part of the trusted ranked evidence.
6622
+ */
6623
+ symbol_chain?: (InspectEvidenceSection | null)
6456
6624
  }
6457
6625
  export interface InspectEvidenceSection {
6458
6626
  status: InspectSectionStatus
@@ -6592,10 +6760,9 @@ _meta?: (Meta | null)
6592
6760
  }
6593
6761
  /**
6594
6762
  * Envelope emitted by `fallow list --boundaries --format json`. Surfaces
6595
- * the architecture boundary zones, rules, and (issue #373) the user's
6596
- * pre-expansion `autoDiscover` logical groups so consumers can render
6597
- * grouping intent that `expand_auto_discover` would otherwise flatten out
6598
- * 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[]`.
6599
6766
  */
6600
6767
  export interface ListBoundariesOutput {
6601
6768
  boundaries: BoundariesListing
@@ -6632,10 +6799,10 @@ from: string
6632
6799
  allow: string[]
6633
6800
  }
6634
6801
  /**
6635
- * A pre-expansion `autoDiscover` logical group surfaced for observability
6636
- * (issue #373). Captured during `expand_auto_discover` so consumers can
6637
- * see the user-authored parent name and grouping intent after expansion
6638
- * 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`].
6639
6806
  */
6640
6807
  export interface BoundariesListLogicalGroup {
6641
6808
  name: string
@@ -6723,7 +6890,7 @@ elapsed_ms: ElapsedMs
6723
6890
  /**
6724
6891
  * Functions and synthetic template entries exceeding complexity
6725
6892
  * thresholds, sorted by the --sort criteria. Each entry wraps its
6726
- * inner [`ComplexityViolation`] payload (flattened on the wire) with
6893
+ * inner `ComplexityViolation` payload (flattened on the wire) with
6727
6894
  * the typed `actions` list and an optional audit-mode `introduced`
6728
6895
  * flag.
6729
6896
  */
@@ -6768,7 +6935,7 @@ prop_drilling_chains?: PropDrillingChainFinding[]
6768
6935
  /**
6769
6936
  * Hotspot entries combining git churn with complexity. Only present when
6770
6937
  * --hotspots is used. Sorted by score descending (highest risk first).
6771
- * Each entry wraps its inner [`HotspotEntry`] payload (flattened on the
6938
+ * Each entry wraps its inner `HotspotEntry` payload (flattened on the
6772
6939
  * wire) with a typed `actions` list.
6773
6940
  */
6774
6941
  hotspots?: HotspotFinding[]
@@ -6793,7 +6960,7 @@ large_functions?: LargeFunctionEntry[]
6793
6960
  /**
6794
6961
  * Ranked refactoring recommendations. Only present when --targets is used.
6795
6962
  * Sorted by efficiency (priority/effort) descending. Each entry wraps
6796
- * its inner [`RefactoringTarget`] payload (flattened on the wire) with
6963
+ * its inner `RefactoringTarget` payload (flattened on the wire) with
6797
6964
  * a typed `actions` list.
6798
6965
  */
6799
6966
  targets?: RefactoringTargetFinding[]
@@ -6830,7 +6997,7 @@ _meta?: (Meta | null)
6830
6997
  workspace_diagnostics?: WorkspaceDiagnostic[]
6831
6998
  /**
6832
6999
  * Read-only follow-up commands computed from this run's findings. See
6833
- * [`CheckOutput::next_steps`] for the contract.
7000
+ * `CheckOutput::next_steps` for the contract.
6834
7001
  */
6835
7002
  next_steps?: NextStep[]
6836
7003
  }
@@ -6845,7 +7012,7 @@ next_steps?: NextStep[]
6845
7012
  * files in the group, so they answer "what is the health of workspace X" in
6846
7013
  * a single invocation. `files_analyzed` and `functions_above_threshold`
6847
7014
  * summarise the subset for parity with the project-level
6848
- * [`crate::health_types::HealthSummary`].
7015
+ * project-level health summary.
6849
7016
  */
6850
7017
  export interface HealthGroup {
6851
7018
  /**
@@ -6892,7 +7059,7 @@ health_score?: (HealthScore | null)
6892
7059
  /**
6893
7060
  * Findings restricted to files in this group. Each entry is the typed
6894
7061
  * [`HealthFinding`] wrapper around a
6895
- * [`ComplexityViolation`](crate::health_types::ComplexityViolation)
7062
+ * `ComplexityViolation`
6896
7063
  * payload.
6897
7064
  */
6898
7065
  findings?: HealthFinding[]
@@ -6903,7 +7070,7 @@ file_scores?: FileHealthScore[]
6903
7070
  /**
6904
7071
  * Hotspots restricted to files in this group. Each entry is the typed
6905
7072
  * [`HotspotFinding`] wrapper around a
6906
- * [`HotspotEntry`](crate::health_types::HotspotEntry) payload.
7073
+ * `HotspotEntry` payload.
6907
7074
  */
6908
7075
  hotspots?: HotspotFinding[]
6909
7076
  /**
@@ -6913,7 +7080,7 @@ large_functions?: LargeFunctionEntry[]
6913
7080
  /**
6914
7081
  * Refactoring targets in files belonging to this group. Each entry is
6915
7082
  * the typed [`RefactoringTargetFinding`] wrapper around a
6916
- * [`RefactoringTarget`](crate::health_types::RefactoringTarget)
7083
+ * `RefactoringTarget`
6917
7084
  * payload.
6918
7085
  */
6919
7086
  targets?: RefactoringTargetFinding[]
@@ -6921,21 +7088,17 @@ targets?: RefactoringTargetFinding[]
6921
7088
  * Auditable breadcrumb recording why `suppress-line` action hints
6922
7089
  * were omitted from this group's findings. Mirrors the project-level
6923
7090
  * `HealthReport.actions_meta`; populated at construction time when the
6924
- * per-group [`HealthActionContext`](crate::health_types::HealthActionContext)
7091
+ * per-group `HealthActionContext`
6925
7092
  * suppresses inline hints.
6926
7093
  */
6927
7094
  actions_meta?: (HealthActionsMeta | null)
6928
7095
  }
6929
7096
  /**
6930
- * Wire-shape payload for `fallow dupes --format json` (the body that
6931
- * flattens into [`crate::output_envelope::DupesOutput`] and is also
6932
- * emitted under the `dupes` / `duplication` key inside the combined and
6933
- * audit envelopes).
7097
+ * Envelope emitted by `fallow dupes --format json`.
6934
7098
  *
6935
- * Mirrors [`DuplicationReport`] field-for-field, except `clone_groups`
6936
- * and `clone_families` carry the typed wrapper envelopes instead of bare
6937
- * findings, so the schema (and any TS / agent consumer) sees the typed
6938
- * `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.
6939
7102
  */
6940
7103
  export interface DupesOutput {
6941
7104
  schema_version: SchemaVersion
@@ -6947,8 +7110,8 @@ elapsed_ms: ElapsedMs
6947
7110
  clone_groups: CloneGroupFinding[]
6948
7111
  /**
6949
7112
  * Clone families, each wrapped with typed actions. Inner `groups`
6950
- * inside each [`CloneFamilyFinding`] are themselves wrapped as
6951
- * [`CloneGroupFinding`] entries carrying their own `actions[]` (and
7113
+ * inside each `CloneFamilyFinding` are themselves wrapped as
7114
+ * `CloneGroupFinding` entries carrying their own `actions[]` (and
6952
7115
  * optional audit-mode `introduced` flag), so JSON-Schema strict
6953
7116
  * consumers and TS consumers reading `clone_families[].groups[]` see
6954
7117
  * the same shape as the top-level `clone_groups[]` array (preserves
@@ -6970,7 +7133,7 @@ groups?: (DuplicationGroup[] | null)
6970
7133
  _meta?: (Meta | null)
6971
7134
  /**
6972
7135
  * Workspace-discovery diagnostics surfaced during config load
6973
- * (issue #473). See [`CheckOutput::workspace_diagnostics`] for the full
7136
+ * (issue #473). See `CheckOutput::workspace_diagnostics` for the full
6974
7137
  * contract; the same list is repeated on each top-level command's
6975
7138
  * envelope so single-command consumers see it without having to look at
6976
7139
  * a separate top-level field.
@@ -6978,7 +7141,7 @@ _meta?: (Meta | null)
6978
7141
  workspace_diagnostics?: WorkspaceDiagnostic[]
6979
7142
  /**
6980
7143
  * Read-only follow-up commands computed from this run's findings. See
6981
- * [`CheckOutput::next_steps`] for the contract.
7144
+ * `CheckOutput::next_steps` for the contract.
6982
7145
  */
6983
7146
  next_steps?: NextStep[]
6984
7147
  }
@@ -7011,7 +7174,7 @@ clone_families: CloneFamilyFinding[]
7011
7174
  * Wire-shape envelope for an [`AttributedCloneGroup`] finding (per-bucket
7012
7175
  * duplication attribution emitted under `fallow dupes --group-by`).
7013
7176
  * Flattens the attributed group and carries the same typed
7014
- * `CloneGroupAction` array as [`CloneGroupFinding`]; no `introduced`
7177
+ * `CloneGroupAction` array as `CloneGroupFinding`; no `introduced`
7015
7178
  * field because `fallow audit` does not run on grouped output.
7016
7179
  */
7017
7180
  export interface AttributedCloneGroupFinding {
@@ -7020,7 +7183,13 @@ export interface AttributedCloneGroupFinding {
7020
7183
  * this clone group. Ties broken alphabetically (smallest key wins).
7021
7184
  */
7022
7185
  primary_owner: string
7186
+ /**
7187
+ * Number of tokens in the clone group.
7188
+ */
7023
7189
  token_count: number
7190
+ /**
7191
+ * Number of source lines in the clone group.
7192
+ */
7024
7193
  line_count: number
7025
7194
  /**
7026
7195
  * Each instance carries its own `owner` field alongside the standard
@@ -7430,7 +7599,7 @@ thin_wrappers?: ThinWrapperFinding[]
7430
7599
  duplicate_prop_shapes?: DuplicatePropShapeFinding[]
7431
7600
  }
7432
7601
  /**
7433
- * The rendered impact report, derived purely from the store (no analysis run).
7602
+ * The rendered impact report, derived purely from the store.
7434
7603
  */
7435
7604
  export interface ImpactReport {
7436
7605
  schema_version: ImpactReportSchemaVersion
@@ -7526,18 +7695,24 @@ duplication: number
7526
7695
  export interface TrendSummary {
7527
7696
  direction: ImpactTrendDirection
7528
7697
  /**
7529
- * Signed delta in total issues (current minus previous).
7698
+ * Signed delta in total issues, current minus previous.
7530
7699
  */
7531
7700
  total_delta: number
7532
7701
  previous_total: number
7533
7702
  current_total: number
7534
7703
  }
7704
+ /**
7705
+ * A commit-gate containment event recorded by `fallow impact`.
7706
+ */
7535
7707
  export interface ContainmentEvent {
7536
7708
  blocked_at: string
7537
7709
  cleared_at: string
7538
7710
  git_sha?: (string | null)
7539
7711
  blocked_counts: ImpactCounts
7540
7712
  }
7713
+ /**
7714
+ * A resolved or suppressed finding attribution event.
7715
+ */
7541
7716
  export interface ResolutionEvent {
7542
7717
  kind: string
7543
7718
  path: string
@@ -7546,7 +7721,7 @@ git_sha?: (string | null)
7546
7721
  timestamp: string
7547
7722
  }
7548
7723
  /**
7549
- * The cross-repo aggregate report (`fallow impact --all --format json`).
7724
+ * The cross-repo aggregate report, `fallow impact --all --format json`.
7550
7725
  */
7551
7726
  export interface CrossRepoImpactReport {
7552
7727
  schema_version: CrossRepoImpactSchemaVersion
@@ -8179,17 +8354,8 @@ top_files_limit: number
8179
8354
  * One sampled unresolved-callee row.
8180
8355
  */
8181
8356
  export interface SecurityUnresolvedCalleeSample {
8182
- /**
8183
- * Project-relative source path.
8184
- */
8185
8357
  path: string
8186
- /**
8187
- * 1-based source line.
8188
- */
8189
8358
  line: number
8190
- /**
8191
- * 0-based byte column.
8192
- */
8193
8359
  col: number
8194
8360
  reason: SkippedSecurityCalleeReason
8195
8361
  expression_kind: SkippedSecurityCalleeExpressionKind
@@ -8198,9 +8364,6 @@ expression_kind: SkippedSecurityCalleeExpressionKind
8198
8364
  * Count of unresolved callees in one file.
8199
8365
  */
8200
8366
  export interface SecurityUnresolvedCalleeTopFile {
8201
- /**
8202
- * Project-relative source path.
8203
- */
8204
8367
  path: string
8205
8368
  /**
8206
8369
  * Number of unresolved callees in this file.
@@ -8341,13 +8504,7 @@ export interface SecuritySurvivor {
8341
8504
  */
8342
8505
  finding_id: string
8343
8506
  verdict: SecurityVerifierVerdictStatus
8344
- /**
8345
- * Short verifier reason.
8346
- */
8347
8507
  reason?: (string | null)
8348
- /**
8349
- * Short verifier rationale.
8350
- */
8351
8508
  rationale?: (string | null)
8352
8509
  /**
8353
8510
  * Optional verifier-provided confidence or review priority.
@@ -8407,9 +8564,6 @@ suggestion: string
8407
8564
  * One file inside a blind-spot group.
8408
8565
  */
8409
8566
  export interface SecurityBlindSpotFile {
8410
- /**
8411
- * Project-relative source path.
8412
- */
8413
8567
  path: string
8414
8568
  /**
8415
8569
  * Count in the bounded diagnostic sample.
@@ -8429,16 +8583,672 @@ dupes?: (DupesReportPayload | null)
8429
8583
  health?: (HealthReport | null)
8430
8584
  /**
8431
8585
  * Read-only follow-up commands aggregated across the combined run's
8432
- * findings. See [`CheckOutput::next_steps`] for the contract.
8586
+ * findings. See `CheckOutput::next_steps` for the contract.
8433
8587
  */
8434
8588
  next_steps?: NextStep[]
8435
8589
  }
8590
+ /**
8591
+ * Optional `_meta` block for [`CombinedOutput`].
8592
+ */
8436
8593
  export interface CombinedMeta {
8437
8594
  check?: (Meta | null)
8438
8595
  dupes?: (Meta | null)
8439
8596
  health?: (Meta | null)
8440
8597
  telemetry?: (TelemetryMeta | null)
8441
8598
  }
8599
+ /**
8600
+ * The full `fallow audit --brief --format json` envelope. Carries the
8601
+ * informational verdict, the triage and graph-facts orientation stages, plus
8602
+ * the reused "subtract" section (the same dead-code / duplication / complexity
8603
+ * payload `fallow audit --format json` emits).
8604
+ */
8605
+ export interface ReviewBriefOutput {
8606
+ schema_version: ReviewBriefSchemaVersion
8607
+ /**
8608
+ * Fallow CLI version that produced this output.
8609
+ */
8610
+ version: string
8611
+ /**
8612
+ * Command discriminator singleton: always `"audit-brief"`.
8613
+ */
8614
+ command: string
8615
+ triage: DiffTriage
8616
+ graph_facts: GraphFacts
8617
+ partition: PartitionFacts
8618
+ impact_closure: ImpactClosureFacts
8619
+ focus: FocusMap
8620
+ deltas: ReviewDeltas
8621
+ /**
8622
+ * 6.F, headline: reviewer-private weakening signals (tests
8623
+ * removed/skipped, thresholds lowered, suppressions added, security steps
8624
+ * removed). Advisory, never gates, never auto-posted.
8625
+ */
8626
+ weakening: WeakeningSignal[]
8627
+ routing: RoutingFacts
8628
+ decisions: DecisionSurface
8629
+ }
8630
+ /**
8631
+ * Stage 0 of the brief: triage facts derived purely from the diff size.
8632
+ *
8633
+ * `hunks` and `net_lines` are `None` in v1: the file-level audit does not yet
8634
+ * thread a `DiffIndex` (from `report/ci/diff_filter.rs`). They populate later,
8635
+ * on `--diff-file` / `--diff-stdin`, without a schema bump.
8636
+ */
8637
+ export interface DiffTriage {
8638
+ /**
8639
+ * Number of changed files in the audit scope.
8640
+ */
8641
+ files: number
8642
+ /**
8643
+ * Number of diff hunks. `None` in v1 (no diff index threaded yet).
8644
+ */
8645
+ hunks?: (number | null)
8646
+ /**
8647
+ * Net added-minus-removed lines. `None` in v1 (no diff index threaded yet).
8648
+ */
8649
+ net_lines?: (number | null)
8650
+ risk_class: RiskClass
8651
+ review_effort: ReviewEffort
8652
+ }
8653
+ /**
8654
+ * Stage 1 of the brief: graph-derived orientation facts.
8655
+ *
8656
+ * `boundaries_touched` is derived from the run's boundary-violation zones;
8657
+ * `reachable_from` is populated by the impact closure (the affected-not-shown
8658
+ * set: modules the changed code is reachable from / affects, none in the diff).
8659
+ * `exports_added` / `api_width_delta` stay honestly stubbed (`0`) until the
8660
+ * export-surface delta lands. The fields are present and correctly typed so
8661
+ * values fill in later without a schema bump.
8662
+ */
8663
+ export interface GraphFacts {
8664
+ /**
8665
+ * Number of exports added by the changeset. Stubbed to `0` in v1.
8666
+ */
8667
+ exports_added: number
8668
+ /**
8669
+ * Change in public API width (added minus removed exports). Stubbed to `0`
8670
+ * in v1.
8671
+ */
8672
+ api_width_delta: number
8673
+ /**
8674
+ * Root-relative paths of modules the changed code is reachable from / affects
8675
+ * (the impact closure's affected-but-not-in-diff set), deduped and sorted.
8676
+ * Empty when no graph was retained or nothing depends on the changed files.
8677
+ */
8678
+ reachable_from: string[]
8679
+ /**
8680
+ * Architecture boundary zones touched by the changeset, deduped and sorted.
8681
+ * Derived from the run's boundary-violation findings.
8682
+ */
8683
+ boundaries_touched: string[]
8684
+ }
8685
+ /**
8686
+ * Stage 2 of the brief: the partition + order. The changed files split into
8687
+ * coherent BY-MODULE units (the only byte-identical-deterministic clustering
8688
+ * definition straight from the graph), plus a dependency-sensible review ORDER
8689
+ * over those units (definitions before consumers, mechanical/leaf units last,
8690
+ * ties broken by the path sort). Stage 2 sits UNDER the decision surface as a
8691
+ * drill-down; it is the backbone the directed-review loop hands the agent.
8692
+ *
8693
+ * Feature-cluster and concern partitioning are deferred (they need scoring
8694
+ * heuristics whose tie-breaks are a fresh nondeterminism surface).
8695
+ */
8696
+ export interface PartitionFacts {
8697
+ /**
8698
+ * The by-module units, sorted by module directory. Empty when no graph was
8699
+ * retained or no changed file maps to a known module.
8700
+ */
8701
+ units: ReviewUnitFact[]
8702
+ /**
8703
+ * The dependency-sensible review order: module-directory strings,
8704
+ * definitions before consumers, mechanical/leaf units last. A permutation of
8705
+ * the `units` module directories.
8706
+ */
8707
+ order: string[]
8708
+ }
8709
+ /**
8710
+ * One review unit: a coherent by-module cluster of the changed set.
8711
+ */
8712
+ export interface ReviewUnitFact {
8713
+ /**
8714
+ * The module directory the unit covers (root-relative, forward-slashed).
8715
+ * The empty string is the repository-root group.
8716
+ */
8717
+ module_dir: string
8718
+ /**
8719
+ * The changed files in this unit, path-sorted.
8720
+ */
8721
+ files: string[]
8722
+ }
8723
+ /**
8724
+ * Stage 3 of the brief: the impact closure. The transitive
8725
+ * affected-but-not-in-diff set plus the coordination gap. The differentiator a
8726
+ * diff tool fundamentally cannot do, because it has no graph.
8727
+ *
8728
+ * Honest scope (ADR-001, syntactic): the coordination gap is an attention
8729
+ * pointer at the exact inter-module failure mode, NOT a correctness proof.
8730
+ */
8731
+ export interface ImpactClosureFacts {
8732
+ /**
8733
+ * Root-relative paths transitively affected by the changeset (reverse-deps +
8734
+ * re-export chains) that are NOT in the diff, deduped and sorted.
8735
+ */
8736
+ affected_not_shown: string[]
8737
+ /**
8738
+ * Coordination gaps: a changed file exports a contract consumed by a module
8739
+ * absent from the diff. One entry per (changed file, consumer) pair.
8740
+ */
8741
+ coordination_gap: CoordinationGapFact[]
8742
+ }
8743
+ /**
8744
+ * One coordination-gap entry: a changed file exports symbols consumed by a
8745
+ * `consumer_file` that is NOT in the diff. Deduped per (changed, consumer) pair
8746
+ * (firing-precision rule R2).
8747
+ */
8748
+ export interface CoordinationGapFact {
8749
+ /**
8750
+ * Root-relative path of the changed file whose contract is consumed elsewhere.
8751
+ */
8752
+ changed_file: string
8753
+ /**
8754
+ * Root-relative path of the consumer module that is NOT in the diff.
8755
+ */
8756
+ consumer_file: string
8757
+ /**
8758
+ * The exported symbol names the consumer references, sorted.
8759
+ */
8760
+ consumed_symbols: string[]
8761
+ /**
8762
+ * Honest scope note: this is a syntactic attention pointer, not a proof.
8763
+ */
8764
+ note: string
8765
+ }
8766
+ /**
8767
+ * The weighted focus map: the ranked `review-here` units plus the FULL
8768
+ * `deprioritized` escape-hatch list, so nothing is hidden.
8769
+ *
8770
+ * Completeness invariant (the escape-hatch done-condition): the two lists
8771
+ * partition the unit set, so `review_here.len() + deprioritized.len()` equals
8772
+ * the total unit count by construction.
8773
+ */
8774
+ export interface FocusMap {
8775
+ /**
8776
+ * Units labeled `review-here`, ranked by composite score (descending), ties
8777
+ * broken by path for determinism.
8778
+ */
8779
+ review_here: FocusUnit[]
8780
+ /**
8781
+ * EVERY `not-prioritized` unit (the escape hatch). Always present and fully
8782
+ * enumerated so a reviewer can always "show me what you de-prioritized"; the
8783
+ * human brief collapses it by default and re-expands under
8784
+ * `--show-deprioritized`.
8785
+ */
8786
+ deprioritized: FocusUnit[]
8787
+ }
8788
+ /**
8789
+ * One review unit on the focus map: its file, composite score, label, human
8790
+ * reason, and any confidence flags.
8791
+ */
8792
+ export interface FocusUnit {
8793
+ /**
8794
+ * Root-relative path of the changed file this unit covers.
8795
+ */
8796
+ file: string
8797
+ score: FocusScore
8798
+ label: FocusLabel
8799
+ /**
8800
+ * A human-readable reason for the label, built from the present signals.
8801
+ */
8802
+ reason: string
8803
+ /**
8804
+ * Confidence flags (advisory; never lower the score). Sorted, deduped.
8805
+ */
8806
+ confidence?: ConfidenceFlag[]
8807
+ }
8808
+ /**
8809
+ * The composite attention score, with the four deterministic component
8810
+ * sub-scores kept on the wire so the runtime seam can re-weight `total`
8811
+ * without recomputing the signals.
8812
+ */
8813
+ export interface FocusScore {
8814
+ /**
8815
+ * Fan-in/out blast-radius component.
8816
+ */
8817
+ fan_io: number
8818
+ /**
8819
+ * Security source -> sink taint-touch component (0 until a security pass is
8820
+ * threaded onto the brief path; the seam is built and tested).
8821
+ */
8822
+ security_taint: number
8823
+ /**
8824
+ * Risk-zone component (boundary / public-API / security-sensitive).
8825
+ */
8826
+ risk_zone: number
8827
+ /**
8828
+ * Change-shape component (new/widened export, signature change proxy).
8829
+ */
8830
+ change_shape: number
8831
+ /**
8832
+ * The summed total. The paid runtime layer multiplies a runtime hot/cold weight in here.
8833
+ */
8834
+ total: number
8835
+ }
8836
+ /**
8837
+ * Diff-aware deterministic deltas (6.A), framed new-vs-pre-existing against
8838
+ * the audit base snapshot. Each entry is a brief summary/verdict line.
8839
+ *
8840
+ * `public_api` is batch-consolidated to ONE decision per change (rule R1):
8841
+ * the `added` list carries the introduced public-export keys as evidence, but a
8842
+ * reviewer reads "the public surface widened by N", never one decision per
8843
+ * symbol.
8844
+ */
8845
+ export interface ReviewDeltas {
8846
+ /**
8847
+ * Cross-zone boundary EDGES introduced vs base (R2 first-edge-only: one per
8848
+ * `<from_zone>-><to_zone>` pair, never per import). New-vs-pre-existing.
8849
+ */
8850
+ boundary_introduced: string[]
8851
+ /**
8852
+ * Circular dependencies introduced vs base (canonical file-set keys).
8853
+ */
8854
+ cycle_introduced: string[]
8855
+ /**
8856
+ * Exports-aware public-API surface delta: the public-export keys
8857
+ * (`<rel_path>::<name>`) added vs base, resolved through `package.json`
8858
+ * `exports` + re-export reachability. A symbol re-exported only through an
8859
+ * internal barrel NOT in `exports` is absent here (zero delta); one
8860
+ * reachable through an `exports` path is present (exactly one).
8861
+ */
8862
+ public_api_added: string[]
8863
+ }
8864
+ /**
8865
+ * One weakening signal: a category, the file it was detected in, and a short
8866
+ * human-readable evidence string. Reviewer-private; never gates.
8867
+ */
8868
+ export interface WeakeningSignal {
8869
+ kind: WeakeningKind
8870
+ /**
8871
+ * Root-relative path of the changed file the signal was detected in.
8872
+ */
8873
+ file: string
8874
+ /**
8875
+ * Short evidence string (e.g. the offending token or the threshold delta).
8876
+ */
8877
+ evidence: string
8878
+ }
8879
+ /**
8880
+ * The full routing section: one unit per changed source file with a routable
8881
+ * signal. Files with no ownership signal are omitted (no noise).
8882
+ */
8883
+ export interface RoutingFacts {
8884
+ /**
8885
+ * Per-changed-file routing units, sorted by file path.
8886
+ */
8887
+ units: RoutingUnit[]
8888
+ }
8889
+ /**
8890
+ * One routed unit with its experts and bus-factor flag.
8891
+ */
8892
+ export interface RoutingUnit {
8893
+ /**
8894
+ * Root-relative path of the changed file.
8895
+ */
8896
+ file: string
8897
+ /**
8898
+ * The routed expert(s): the CODEOWNERS declared owner when present, else the
8899
+ * top git-blame / recency contributor; empty when no signal is available.
8900
+ */
8901
+ expert: string[]
8902
+ /**
8903
+ * Whether the only qualified owner is a single contributor (bus-factor-1):
8904
+ * a knowledge-concentration risk worth a second reviewer.
8905
+ */
8906
+ bus_factor_one?: boolean
8907
+ }
8908
+ /**
8909
+ * The ranked, capped decision surface plus the set of signal_ids the
8910
+ * deterministic layer emitted (the anti-hallucination allowlist).
8911
+ */
8912
+ export interface DecisionSurface {
8913
+ /**
8914
+ * Ranked decisions, highest consequence first.
8915
+ */
8916
+ decisions: Decision[]
8917
+ /**
8918
+ * Present when more than the cap were extracted.
8919
+ */
8920
+ truncated?: (TruncationNote | null)
8921
+ /**
8922
+ * Every signal_id the deterministic layer emitted, INCLUDING those whose
8923
+ * decision was collapsed below the cap or suppressed. The anti-hallucination
8924
+ * allowlist: an agent decision whose id is absent is rejected.
8925
+ */
8926
+ emitted_signal_ids: string[]
8927
+ }
8928
+ /**
8929
+ * One consequential structural decision, framed as a judgment question for a
8930
+ * human with taste, anchored to a fallow-emitted signal.
8931
+ */
8932
+ export interface Decision {
8933
+ /**
8934
+ * Deterministic anchor to the fallow-emitted candidate this decision frames.
8935
+ * `accept_signal_id` rejects any id not in the emitted set.
8936
+ */
8937
+ signal_id: string
8938
+ category: DecisionCategory
8939
+ /**
8940
+ * The decision framed as a judgment question for the human.
8941
+ */
8942
+ question: string
8943
+ /**
8944
+ * Root-relative file the decision is anchored at.
8945
+ */
8946
+ anchor_file: string
8947
+ /**
8948
+ * 1-based anchor line, when the underlying signal carries one (0 = file head).
8949
+ */
8950
+ anchor_line: number
8951
+ /**
8952
+ * The raw fallow-emitted candidate key the `signal_id` hashes.
8953
+ */
8954
+ signal_key: string
8955
+ /**
8956
+ * The `signal_id` this decision WOULD have had before any rename in this
8957
+ * change (the anchor file's pre-rename path). Present only when the anchor was
8958
+ * renamed. A review-memory layer carries a dismissal across a `git mv`: if
8959
+ * `previous_signal_id` was dismissed in an earlier PR, treat this decision as
8960
+ * dismissed too. Keeps `signal_id` itself exact + deterministic.
8961
+ */
8962
+ previous_signal_id?: (string | null)
8963
+ /**
8964
+ * Blast radius: count of modules affected beyond the diff by this decision.
8965
+ */
8966
+ blast: number
8967
+ /**
8968
+ * `blast * reversibility_weight`: the rank key (sorted descending).
8969
+ */
8970
+ consequence: number
8971
+ /**
8972
+ * The routed expert(s) to ask, from ownership routing. Empty when no
8973
+ * ownership signal is available for the anchor file.
8974
+ */
8975
+ expert: string[]
8976
+ /**
8977
+ * Whether the anchor file's only qualified owner is one person.
8978
+ */
8979
+ bus_factor_one?: boolean
8980
+ /**
8981
+ * Honest per-decision count: in-repo modules OUTSIDE the diff that already
8982
+ * depend on this decision's anchor. This is the DISPLAY number (taste
8983
+ * ownership: the human reads reversibility from the count itself), distinct
8984
+ * from `blast` (the project-wide proxy used only for ranking). Never a door
8985
+ * label. Internal-only by construction, so it cannot see a published library's
8986
+ * external consumers; the public-API trade-off clause names that risk in prose.
8987
+ */
8988
+ internal_consumer_count: number
8989
+ /**
8990
+ * The named structural sacrifice this change makes, stated as a fact, never a
8991
+ * recommendation (e.g. "Couples `app` to `infra`; 4 in-repo modules already
8992
+ * depend on this anchor."). A sibling fact to `question`; it never tells the
8993
+ * human what to choose.
8994
+ */
8995
+ tradeoff: string
8996
+ }
8997
+ /**
8998
+ * A note for decisions collapsed below the cap.
8999
+ */
9000
+ export interface TruncationNote {
9001
+ /**
9002
+ * How many decisions were collapsed below the cap.
9003
+ */
9004
+ collapsed: number
9005
+ /**
9006
+ * Human-readable collapse reason.
9007
+ */
9008
+ reason: string
9009
+ }
9010
+ /**
9011
+ * The `fallow review --walkthrough-guide` envelope: the current digest + schema
9012
+ * the agent fetches. The tool owns this; the skill stays thin (it fetches this
9013
+ * rather than embedding a frozen copy). Always emitted with exit 0.
9014
+ */
9015
+ export interface WalkthroughGuide {
9016
+ schema_version: ReviewBriefSchemaVersion
9017
+ /**
9018
+ * Fallow CLI version that produced this guide.
9019
+ */
9020
+ version: string
9021
+ /**
9022
+ * Command discriminator singleton: always `"review-walkthrough-guide"`.
9023
+ */
9024
+ command: string
9025
+ /**
9026
+ * The deterministic graph-snapshot hash pinned into the digest. The agent
9027
+ * echoes it back; a mismatch on reentry refuses the payload as stale.
9028
+ */
9029
+ graph_snapshot_hash: string
9030
+ digest: ReviewBriefOutput
9031
+ direction: ReviewDirection
9032
+ /**
9033
+ * The per-hunk change anchors: one stable id per changed region. An agent
9034
+ * may cite a `change_anchor` as a judgment anchor in addition to an emitted
9035
+ * `signal_id`, so a trade-off about a changed region with no graph finding
9036
+ * can still anchor (and be post-validated) rather than hallucinate.
9037
+ */
9038
+ change_anchors: ChangeAnchor[]
9039
+ agent_schema: AgentSchema
9040
+ /**
9041
+ * The injection-resistance note (digest is graph-only; PR prose untrusted).
9042
+ */
9043
+ injection_note: string
9044
+ }
9045
+ /**
9046
+ * The review direction artifact: the order to review in, the coherent units,
9047
+ * and per-unit concern lens + out-of-diff + expert. A minimal projection of the
9048
+ * EXISTING graph facts (routing units + impact closure); the full weighted-focus
9049
+ * engine is a later epic. Graph-derived only (injection-resistant).
9050
+ */
9051
+ export interface ReviewDirection {
9052
+ /**
9053
+ * The dependency-sensible review order: unit file paths, units carrying
9054
+ * out-of-diff consumers first (review the load-bearing definitions before
9055
+ * the mechanical units).
9056
+ */
9057
+ order: string[]
9058
+ /**
9059
+ * Coherent review units, in `order`.
9060
+ */
9061
+ units: DirectionUnit[]
9062
+ }
9063
+ /**
9064
+ * One directed review unit projected from the graph: a file the change touches,
9065
+ * the concern to check, the out-of-diff consumers it must account for, and the
9066
+ * routed expert. Graph-derived only (routing + impact closure), NEVER from prose.
9067
+ */
9068
+ export interface DirectionUnit {
9069
+ /**
9070
+ * Root-relative path of the unit to review.
9071
+ */
9072
+ file: string
9073
+ /**
9074
+ * The concern lens the agent should check for this unit, derived from the
9075
+ * unit's risk signals (impact-closure consumers vs a plain touched file).
9076
+ */
9077
+ concern_lens: string
9078
+ /**
9079
+ * Per-unit review-effort budget: the weighted-focus composite score for
9080
+ * this file. A cloud fan-out spends AI passes/verifiers PROPORTIONAL to this
9081
+ * (higher = review harder); a local single-agent loop can ignore it.
9082
+ */
9083
+ scoring_budget: number
9084
+ /**
9085
+ * Root-relative paths of modules affected by this unit but NOT in the diff
9086
+ * (the out-of-diff context the agent must reason about).
9087
+ */
9088
+ out_of_diff: string[]
9089
+ /**
9090
+ * Routed expert(s), when ownership signals are available.
9091
+ */
9092
+ expert: string[]
9093
+ }
9094
+ /**
9095
+ * One stable per-hunk CHANGE ANCHOR: a changed region the agent may cite as a
9096
+ * judgment anchor IN ADDITION to a `signal_id`. Where a `signal_id` anchors a
9097
+ * graph FINDING ("fallow emitted this exact finding"), a change_anchor anchors
9098
+ * only a changed REGION ("fallow confirms this region changed") , a strictly
9099
+ * weaker guarantee, surfaced as `anchor_kind` on the accepted judgment so a
9100
+ * consumer can tell the two apart. Graph/diff-derived; NEVER from prose.
9101
+ */
9102
+ export interface ChangeAnchor {
9103
+ /**
9104
+ * Stable, CONTENT-addressed id: `chg:<16-hex>` over the file path + the
9105
+ * normalized added text (line numbers are NOT hashed, so an edit above the
9106
+ * hunk or a whitespace-only change does not move the id).
9107
+ */
9108
+ change_anchor: string
9109
+ /**
9110
+ * Root-relative path of the changed file.
9111
+ */
9112
+ file: string
9113
+ /**
9114
+ * 1-based first line of the hunk in the head file (display/deep-link only;
9115
+ * NOT part of the id).
9116
+ */
9117
+ start_line: number
9118
+ /**
9119
+ * Number of added lines in the hunk (display only; NOT part of the id).
9120
+ */
9121
+ line_count: number
9122
+ /**
9123
+ * Rename-durable anchor: the id this same hunk would have had under the
9124
+ * pre-rename path. `None` unless the file was renamed in this change, so an
9125
+ * agent that cited the anchor before a `git mv` still resolves.
9126
+ */
9127
+ previous_change_anchor?: (string | null)
9128
+ }
9129
+ /**
9130
+ * The shape the agent must return, embedded in the guide so a thin skill needs
9131
+ * no frozen copy. Documents the anchoring + staleness contract in the wire.
9132
+ */
9133
+ export interface AgentSchema {
9134
+ /**
9135
+ * How the agent must structure each judgment: cite an emitted `signal_id`,
9136
+ * add free-text `framing` (non-deterministic, fenced), an optional `concern`.
9137
+ */
9138
+ judgment_shape: string
9139
+ /**
9140
+ * The agent MUST echo this `graph_snapshot_hash` back in its JSON; a
9141
+ * mismatch on reentry REFUSES the payload as stale.
9142
+ */
9143
+ echo_field: string
9144
+ /**
9145
+ * The anchoring rule name.
9146
+ */
9147
+ anchoring_rule: string
9148
+ }
9149
+ /**
9150
+ * The `fallow review --walkthrough-file` validation envelope: the result of
9151
+ * post-validating the agent's judgment against the live graph. Always exit 0.
9152
+ */
9153
+ export interface WalkthroughValidation {
9154
+ schema_version: ReviewBriefSchemaVersion
9155
+ /**
9156
+ * Fallow CLI version that produced this validation.
9157
+ */
9158
+ version: string
9159
+ /**
9160
+ * Command discriminator singleton: always `"review-walkthrough-validation"`.
9161
+ */
9162
+ command: string
9163
+ /**
9164
+ * The current run's deterministic graph-snapshot hash.
9165
+ */
9166
+ graph_snapshot_hash: string
9167
+ /**
9168
+ * `true` when the agent's echoed hash != the current hash (the tree moved):
9169
+ * the WHOLE payload is refused, `accepted` is empty.
9170
+ */
9171
+ stale: boolean
9172
+ /**
9173
+ * Judgments that cite a real fallow-emitted signal, framing fenced.
9174
+ */
9175
+ accepted: AcceptedJudgment[]
9176
+ /**
9177
+ * Judgments rejected (unanchored signal id, or all-rejected when stale).
9178
+ */
9179
+ rejected: RejectedJudgment[]
9180
+ /**
9181
+ * Count of accepted judgments.
9182
+ */
9183
+ accepted_count: number
9184
+ /**
9185
+ * Count of rejected judgments.
9186
+ */
9187
+ rejected_count: number
9188
+ /**
9189
+ * Count of accepted judgments whose `signal_id` resolved against the live
9190
+ * allowlist. Zero unanchored when this equals `accepted_count` and there are
9191
+ * no rejections (the clean done-condition).
9192
+ */
9193
+ unanchored_count: number
9194
+ }
9195
+ /**
9196
+ * One accepted judgment: the real anchored signal passed through with the
9197
+ * agent's framing FENCED as non-deterministic.
9198
+ */
9199
+ export interface AcceptedJudgment {
9200
+ /**
9201
+ * The fallow-emitted `signal_id` (verified against the allowlist). Empty
9202
+ * when this judgment was anchored by a `change_anchor` instead.
9203
+ */
9204
+ signal_id: string
9205
+ /**
9206
+ * The fallow-emitted `change_anchor` (verified against the allowlist). Empty
9207
+ * when this judgment was anchored by a `signal_id`.
9208
+ */
9209
+ change_anchor: string
9210
+ /**
9211
+ * Which anchor resolved: `"signal"` (a graph FINDING, the strong anchor) or
9212
+ * `"change"` (a changed REGION only, the weaker anchor). Lets a consumer
9213
+ * distinguish a finding-anchored judgment from a region-anchored one rather
9214
+ * than collapsing both into one accepted bucket.
9215
+ */
9216
+ anchor_kind: string
9217
+ /**
9218
+ * The agent's fenced free-text framing.
9219
+ */
9220
+ agent_framing: string
9221
+ /**
9222
+ * The agent's optional concern category.
9223
+ */
9224
+ concern?: (string | null)
9225
+ /**
9226
+ * Hard fence: always `false`. The framing is agent prose, never a
9227
+ * deterministic fallow result, so it never gates or auto-posts.
9228
+ */
9229
+ deterministic: boolean
9230
+ }
9231
+ /**
9232
+ * One rejected judgment plus the reason it was rejected.
9233
+ */
9234
+ export interface RejectedJudgment {
9235
+ /**
9236
+ * The `signal_id` the agent cited (fallow never emitted it). Empty when the
9237
+ * judgment cited a `change_anchor` instead.
9238
+ */
9239
+ signal_id: string
9240
+ /**
9241
+ * The `change_anchor` the agent cited (fallow never emitted it). Empty when
9242
+ * the judgment cited a `signal_id` instead.
9243
+ */
9244
+ change_anchor: string
9245
+ /**
9246
+ * The rejection reason: `unanchored-signal-id` (cited a signal fallow did
9247
+ * not emit), `unknown-change-anchor` (cited a region fallow did not emit),
9248
+ * or `stale-snapshot` (the tree moved).
9249
+ */
9250
+ reason: string
9251
+ }
8442
9252
  /**
8443
9253
  * Single CodeClimate-compatible issue inside [`CodeClimateOutput`].
8444
9254
  */
@@ -8450,6 +9260,15 @@ categories: string[]
8450
9260
  severity: CodeClimateSeverity
8451
9261
  fingerprint: string
8452
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)
8453
9272
  }
8454
9273
  /**
8455
9274
  * Location block inside [`CodeClimateIssue::location`].