fallow 2.91.0 → 2.92.1
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/README.md +2 -2
- package/package.json +10 -10
- package/schema.json +122 -2
- package/skills/fallow/SKILL.md +15 -11
- package/skills/fallow/references/cli-reference.md +162 -68
- package/skills/fallow/references/gotchas.md +1 -1
- package/skills/fallow/references/patterns.md +14 -1
- package/types/output-contract.d.ts +556 -77
|
@@ -71,7 +71,7 @@ kind: "dupes"
|
|
|
71
71
|
kind: "dead-code-grouped"
|
|
72
72
|
}) | (ImpactReport & {
|
|
73
73
|
kind: "impact"
|
|
74
|
-
}) | (SecurityOutput & {
|
|
74
|
+
}) | ((SecurityOutput | SecuritySummaryOutput) & {
|
|
75
75
|
kind: "security"
|
|
76
76
|
}) | (CheckOutput & {
|
|
77
77
|
kind: "dead-code"
|
|
@@ -170,7 +170,7 @@ export type IssueAction = (FixAction | SuppressLineAction | SuppressFileAction |
|
|
|
170
170
|
* Discriminant string for [`FixAction`]. Kebab-case per the JSON output
|
|
171
171
|
* contract.
|
|
172
172
|
*/
|
|
173
|
-
export type FixActionType = ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "refactor-cycle" | "refactor-re-export-cycle" | "refactor-boundary" | "export-type" | "remove-catalog-entry" | "remove-empty-catalog-group" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference" | "remove-dependency-override" | "fix-dependency-override")
|
|
173
|
+
export type FixActionType = ("remove-export" | "delete-file" | "remove-dependency" | "move-dependency" | "remove-enum-member" | "remove-class-member" | "resolve-import" | "install-dependency" | "remove-duplicate" | "move-to-dev" | "refactor-cycle" | "refactor-re-export-cycle" | "refactor-boundary" | "export-type" | "remove-catalog-entry" | "remove-empty-catalog-group" | "update-catalog-reference" | "add-catalog-entry" | "remove-catalog-reference" | "remove-dependency-override" | "fix-dependency-override" | "resolve-policy-violation")
|
|
174
174
|
/**
|
|
175
175
|
* Singleton discriminant for [`SuppressLineAction`].
|
|
176
176
|
*/
|
|
@@ -232,6 +232,17 @@ export type MemberKind = ("enum_member" | "class_method" | "class_property" | "n
|
|
|
232
232
|
* Discriminator for [`ReExportCycle`]: which structural shape was detected.
|
|
233
233
|
*/
|
|
234
234
|
export type ReExportCycleKind = ("multi-node" | "self-loop")
|
|
235
|
+
/**
|
|
236
|
+
* Which rule-pack rule kind produced a [`PolicyViolation`].
|
|
237
|
+
*/
|
|
238
|
+
export type PolicyRuleKind = ("banned-call" | "banned-import")
|
|
239
|
+
/**
|
|
240
|
+
* Effective severity of a single [`PolicyViolation`]. Per-rule `severity`
|
|
241
|
+
* overrides the `rules."policy-violation"` master; `off` rules emit nothing,
|
|
242
|
+
* so only `error` and `warn` appear on the wire. The exit-code gate inspects
|
|
243
|
+
* this per-finding value, not the master severity.
|
|
244
|
+
*/
|
|
245
|
+
export type PolicyViolationSeverity = ("error" | "warn")
|
|
235
246
|
/**
|
|
236
247
|
* The origin of a stale suppression: inline comment or JSDoc tag.
|
|
237
248
|
*/
|
|
@@ -328,6 +339,12 @@ kind: "tsconfig-reference-dir-missing"
|
|
|
328
339
|
*/
|
|
329
340
|
size_bytes: number
|
|
330
341
|
kind: "skipped-large-file"
|
|
342
|
+
} | {
|
|
343
|
+
/**
|
|
344
|
+
* On-disk size of the skipped file in bytes.
|
|
345
|
+
*/
|
|
346
|
+
size_bytes: number
|
|
347
|
+
kind: "skipped-minified-file"
|
|
331
348
|
})
|
|
332
349
|
/**
|
|
333
350
|
* Discriminant for [`CloneGroupAction::kind`]. Mirrors the action types
|
|
@@ -606,12 +623,18 @@ export type ImpactTrendDirection = ("improving" | "declining" | "stable")
|
|
|
606
623
|
* The `fallow security --format json` schema version. Independently versioned
|
|
607
624
|
* from the main contract, mirroring `ImpactReportSchemaVersion`.
|
|
608
625
|
*/
|
|
609
|
-
export type SecuritySchemaVersion = ("1" | "2")
|
|
626
|
+
export type SecuritySchemaVersion = ("1" | "2" | "3" | "4" | "5" | "6")
|
|
627
|
+
/**
|
|
628
|
+
* Severity level for rules.
|
|
629
|
+
*
|
|
630
|
+
* Controls whether an issue type causes CI failure (`error`), is reported
|
|
631
|
+
* without failing (`warn`), or is suppressed entirely (`off`).
|
|
632
|
+
*/
|
|
633
|
+
export type Severity = ("error" | "warn" | "off")
|
|
610
634
|
/**
|
|
611
|
-
* Gate mode for `fallow security --gate <mode
|
|
612
|
-
* the value `newly-reachable`.
|
|
635
|
+
* Gate mode for `fallow security --gate <mode>`.
|
|
613
636
|
*/
|
|
614
|
-
export type SecurityGateMode = "new"
|
|
637
|
+
export type SecurityGateMode = ("new" | "newly-reachable")
|
|
615
638
|
/**
|
|
616
639
|
* Gate verdict on the wire. `fail` is the CI-state token; human output renders
|
|
617
640
|
* it as "REVIEW REQUIRED" because these stay unverified candidates, never
|
|
@@ -645,6 +668,10 @@ export type SecurityDeadCodeKind = ("unused-file" | "unused-export")
|
|
|
645
668
|
* rank, never gate).
|
|
646
669
|
*/
|
|
647
670
|
export type TaintConfidence = ("arg-level" | "module-level")
|
|
671
|
+
/**
|
|
672
|
+
* Static URL construction shape captured for URL-shaped security sinks.
|
|
673
|
+
*/
|
|
674
|
+
export type SecurityUrlShape = ("fixed-origin-dynamic-path" | "dynamic-origin")
|
|
648
675
|
/**
|
|
649
676
|
* Runtime coverage state for the function enclosing a security sink.
|
|
650
677
|
* This is production-observation evidence, not an exploitability verdict.
|
|
@@ -654,6 +681,15 @@ export type SecurityRuntimeState = ("runtime-hot" | "runtime-cold" | "never-exec
|
|
|
654
681
|
* Defensive control family detected on a source to sink path.
|
|
655
682
|
*/
|
|
656
683
|
export type SecurityControlKind = ("sanitization" | "validation" | "authentication" | "authorization")
|
|
684
|
+
/**
|
|
685
|
+
* Why a sink-shaped callee could not be flattened into a static catalogue
|
|
686
|
+
* path.
|
|
687
|
+
*/
|
|
688
|
+
export type SkippedSecurityCalleeReason = ("computed-member" | "dynamic-dispatch" | "unsupported-assignment-object")
|
|
689
|
+
/**
|
|
690
|
+
* Syntactic expression shape for a skipped security callee.
|
|
691
|
+
*/
|
|
692
|
+
export type SkippedSecurityCalleeExpressionKind = ("static-member-expression" | "computed-member-expression" | "identifier" | "other")
|
|
657
693
|
/**
|
|
658
694
|
* Discriminator value for [`CodeClimateIssue::kind`].
|
|
659
695
|
*/
|
|
@@ -679,11 +715,20 @@ command: AuditCommand
|
|
|
679
715
|
verdict: AuditVerdict
|
|
680
716
|
changed_files_count: number
|
|
681
717
|
base_ref: string
|
|
718
|
+
/**
|
|
719
|
+
* Human-readable provenance of `base_ref`, e.g. `merge-base with
|
|
720
|
+
* origin/main`, `local main`, or `FALLOW_AUDIT_BASE=upstream/main`.
|
|
721
|
+
* Present when the base was auto-detected or set via `FALLOW_AUDIT_BASE`;
|
|
722
|
+
* absent for an explicit `--base` (the ref the user typed is already
|
|
723
|
+
* self-describing).
|
|
724
|
+
*/
|
|
725
|
+
base_description?: (string | null)
|
|
682
726
|
head_sha?: (string | null)
|
|
683
727
|
elapsed_ms: ElapsedMs
|
|
684
728
|
base_snapshot_skipped?: (boolean | null)
|
|
685
729
|
summary: AuditSummary
|
|
686
730
|
attribution: AuditAttribution
|
|
731
|
+
_meta?: (Meta | null)
|
|
687
732
|
dead_code?: (CheckOutput | null)
|
|
688
733
|
duplication?: (DupesReportPayload | null)
|
|
689
734
|
complexity?: (HealthReport | null)
|
|
@@ -710,6 +755,88 @@ complexity_inherited: number
|
|
|
710
755
|
duplication_introduced: number
|
|
711
756
|
duplication_inherited: number
|
|
712
757
|
}
|
|
758
|
+
/**
|
|
759
|
+
* Metric and rule definitions emitted under `_meta` when `--explain` is
|
|
760
|
+
* passed (always present in MCP responses). Helps AI agents and CI systems
|
|
761
|
+
* interpret metric values without re-reading the docs site.
|
|
762
|
+
*/
|
|
763
|
+
export interface Meta {
|
|
764
|
+
/**
|
|
765
|
+
* URL to the documentation page for this command.
|
|
766
|
+
*/
|
|
767
|
+
docs?: (string | null)
|
|
768
|
+
/**
|
|
769
|
+
* Local telemetry correlation metadata for agent follow-up runs.
|
|
770
|
+
*/
|
|
771
|
+
telemetry?: (TelemetryMeta | null)
|
|
772
|
+
/**
|
|
773
|
+
* Per-field definitions for envelope fields and action payload fields.
|
|
774
|
+
*/
|
|
775
|
+
field_definitions?: {
|
|
776
|
+
[k: string]: string
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Per-metric definitions: name, description, range, interpretation.
|
|
780
|
+
*/
|
|
781
|
+
metrics?: {
|
|
782
|
+
[k: string]: MetaMetric
|
|
783
|
+
}
|
|
784
|
+
/**
|
|
785
|
+
* Per-rule definitions for check command output.
|
|
786
|
+
*/
|
|
787
|
+
rules?: {
|
|
788
|
+
[k: string]: MetaRule
|
|
789
|
+
}
|
|
790
|
+
}
|
|
791
|
+
/**
|
|
792
|
+
* Privacy-safe local run metadata emitted for JSON consumers.
|
|
793
|
+
*/
|
|
794
|
+
export interface TelemetryMeta {
|
|
795
|
+
/**
|
|
796
|
+
* Ephemeral local token that may be passed to the hidden `--parent-run`
|
|
797
|
+
* flag on a later command. It is not derived from repository, path, user,
|
|
798
|
+
* machine, project, or cloud data.
|
|
799
|
+
*/
|
|
800
|
+
analysis_run_id?: (string | null)
|
|
801
|
+
}
|
|
802
|
+
/**
|
|
803
|
+
* Single-metric definition inside [`Meta::metrics`].
|
|
804
|
+
*/
|
|
805
|
+
export interface MetaMetric {
|
|
806
|
+
/**
|
|
807
|
+
* Human-readable metric name.
|
|
808
|
+
*/
|
|
809
|
+
name?: (string | null)
|
|
810
|
+
/**
|
|
811
|
+
* What this metric measures and how it is computed.
|
|
812
|
+
*/
|
|
813
|
+
description?: (string | null)
|
|
814
|
+
/**
|
|
815
|
+
* Valid value range (e.g., `"[0, 100]"`).
|
|
816
|
+
*/
|
|
817
|
+
range?: (string | null)
|
|
818
|
+
/**
|
|
819
|
+
* How to read the value (e.g., `"lower is better"`).
|
|
820
|
+
*/
|
|
821
|
+
interpretation?: (string | null)
|
|
822
|
+
}
|
|
823
|
+
/**
|
|
824
|
+
* Single-rule definition inside [`Meta::rules`].
|
|
825
|
+
*/
|
|
826
|
+
export interface MetaRule {
|
|
827
|
+
/**
|
|
828
|
+
* Human-readable rule name.
|
|
829
|
+
*/
|
|
830
|
+
name?: (string | null)
|
|
831
|
+
/**
|
|
832
|
+
* What this rule detects.
|
|
833
|
+
*/
|
|
834
|
+
description?: (string | null)
|
|
835
|
+
/**
|
|
836
|
+
* URL to the rule documentation.
|
|
837
|
+
*/
|
|
838
|
+
docs?: (string | null)
|
|
839
|
+
}
|
|
713
840
|
/**
|
|
714
841
|
* Envelope emitted by `fallow dead-code --format json` (plus the `check`
|
|
715
842
|
* block inside the combined and audit envelopes).
|
|
@@ -837,6 +964,25 @@ re_export_cycles?: ReExportCycleFinding[]
|
|
|
837
964
|
* array natively.
|
|
838
965
|
*/
|
|
839
966
|
boundary_violations?: BoundaryViolationFinding[]
|
|
967
|
+
/**
|
|
968
|
+
* Files that matched no architecture boundary zone while
|
|
969
|
+
* `boundaries.coverage.requireAllFiles` was enabled.
|
|
970
|
+
*/
|
|
971
|
+
boundary_coverage_violations?: BoundaryCoverageViolationFinding[]
|
|
972
|
+
/**
|
|
973
|
+
* Calls from zoned files to callees forbidden for that zone via
|
|
974
|
+
* `boundaries.calls.forbidden`. Wrapped in
|
|
975
|
+
* [`BoundaryCallViolationFinding`] so each entry carries a typed
|
|
976
|
+
* `actions` array natively.
|
|
977
|
+
*/
|
|
978
|
+
boundary_call_violations?: BoundaryCallViolationFinding[]
|
|
979
|
+
/**
|
|
980
|
+
* Banned calls and banned imports matched by declarative rule packs
|
|
981
|
+
* (`rulePacks` config). Wrapped in [`PolicyViolationFinding`] so each
|
|
982
|
+
* entry carries a typed `actions` array natively. Each finding carries
|
|
983
|
+
* its effective per-rule severity.
|
|
984
|
+
*/
|
|
985
|
+
policy_violations?: PolicyViolationFinding[]
|
|
840
986
|
/**
|
|
841
987
|
* Suppression comments or JSDoc tags that no longer match any issue.
|
|
842
988
|
*/
|
|
@@ -979,6 +1125,18 @@ re_export_cycles?: number
|
|
|
979
1125
|
* Imports that cross architecture boundary rules.
|
|
980
1126
|
*/
|
|
981
1127
|
boundary_violations: number
|
|
1128
|
+
/**
|
|
1129
|
+
* Files that match no architecture boundary zone.
|
|
1130
|
+
*/
|
|
1131
|
+
boundary_coverage_violations?: number
|
|
1132
|
+
/**
|
|
1133
|
+
* Calls from zoned files to callees forbidden for that zone.
|
|
1134
|
+
*/
|
|
1135
|
+
boundary_call_violations?: number
|
|
1136
|
+
/**
|
|
1137
|
+
* Banned calls and banned imports matched by declarative rule packs.
|
|
1138
|
+
*/
|
|
1139
|
+
policy_violations?: number
|
|
982
1140
|
/**
|
|
983
1141
|
* Suppression comments that no longer match a finding.
|
|
984
1142
|
*/
|
|
@@ -1666,7 +1824,7 @@ introduced?: (AuditIntroduced | null)
|
|
|
1666
1824
|
*/
|
|
1667
1825
|
export interface TestOnlyDependencyFinding {
|
|
1668
1826
|
/**
|
|
1669
|
-
* Production dependency that is only imported by test files
|
|
1827
|
+
* Production dependency that is only imported by test files , consider
|
|
1670
1828
|
* moving to devDependencies.
|
|
1671
1829
|
*/
|
|
1672
1830
|
package_name: string
|
|
@@ -1837,6 +1995,124 @@ actions: IssueAction[]
|
|
|
1837
1995
|
*/
|
|
1838
1996
|
introduced?: (AuditIntroduced | null)
|
|
1839
1997
|
}
|
|
1998
|
+
/**
|
|
1999
|
+
* Wire-shape envelope for a [`BoundaryCoverageViolation`] finding. Carries
|
|
2000
|
+
* actions for assigning the file to a zone or explicitly allowing it to stay
|
|
2001
|
+
* unmatched.
|
|
2002
|
+
*/
|
|
2003
|
+
export interface BoundaryCoverageViolationFinding {
|
|
2004
|
+
/**
|
|
2005
|
+
* The unmatched source file.
|
|
2006
|
+
*/
|
|
2007
|
+
path: string
|
|
2008
|
+
/**
|
|
2009
|
+
* 1-based line number used for diagnostics.
|
|
2010
|
+
*/
|
|
2011
|
+
line: number
|
|
2012
|
+
/**
|
|
2013
|
+
* 0-based byte column offset used for diagnostics.
|
|
2014
|
+
*/
|
|
2015
|
+
col: number
|
|
2016
|
+
/**
|
|
2017
|
+
* Suggested next steps.
|
|
2018
|
+
*/
|
|
2019
|
+
actions: IssueAction[]
|
|
2020
|
+
/**
|
|
2021
|
+
* Set by the audit pass when this finding is introduced relative to
|
|
2022
|
+
* the merge-base.
|
|
2023
|
+
*/
|
|
2024
|
+
introduced?: (AuditIntroduced | null)
|
|
2025
|
+
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Wire-shape envelope for a [`BoundaryCallViolation`] finding. Carries
|
|
2028
|
+
* actions for refactoring the forbidden call out of the zone or suppressing
|
|
2029
|
+
* it with the shared `boundary-violation` token.
|
|
2030
|
+
*/
|
|
2031
|
+
export interface BoundaryCallViolationFinding {
|
|
2032
|
+
/**
|
|
2033
|
+
* The zoned source file making the forbidden call.
|
|
2034
|
+
*/
|
|
2035
|
+
path: string
|
|
2036
|
+
/**
|
|
2037
|
+
* 1-based line number of the call site.
|
|
2038
|
+
*/
|
|
2039
|
+
line: number
|
|
2040
|
+
/**
|
|
2041
|
+
* 0-based byte column offset of the call site.
|
|
2042
|
+
*/
|
|
2043
|
+
col: number
|
|
2044
|
+
/**
|
|
2045
|
+
* The zone the calling file is classified into.
|
|
2046
|
+
*/
|
|
2047
|
+
zone: string
|
|
2048
|
+
/**
|
|
2049
|
+
* The callee path as written at the call site (e.g. `cp.exec`).
|
|
2050
|
+
*/
|
|
2051
|
+
callee: string
|
|
2052
|
+
/**
|
|
2053
|
+
* The configured pattern that matched (e.g. `child_process.*`), so
|
|
2054
|
+
* consumers can see both the written path and the rule that fired.
|
|
2055
|
+
*/
|
|
2056
|
+
pattern: string
|
|
2057
|
+
/**
|
|
2058
|
+
* Suggested next steps.
|
|
2059
|
+
*/
|
|
2060
|
+
actions: IssueAction[]
|
|
2061
|
+
/**
|
|
2062
|
+
* Set by the audit pass when this finding is introduced relative to
|
|
2063
|
+
* the merge-base.
|
|
2064
|
+
*/
|
|
2065
|
+
introduced?: (AuditIntroduced | null)
|
|
2066
|
+
}
|
|
2067
|
+
/**
|
|
2068
|
+
* Wire-shape envelope for a [`PolicyViolation`] finding. Carries actions for
|
|
2069
|
+
* replacing the banned call or import, or suppressing it with the
|
|
2070
|
+
* `policy-violation` token.
|
|
2071
|
+
*/
|
|
2072
|
+
export interface PolicyViolationFinding {
|
|
2073
|
+
/**
|
|
2074
|
+
* The source file containing the banned call or import.
|
|
2075
|
+
*/
|
|
2076
|
+
path: string
|
|
2077
|
+
/**
|
|
2078
|
+
* 1-based line number of the call site or import declaration.
|
|
2079
|
+
*/
|
|
2080
|
+
line: number
|
|
2081
|
+
/**
|
|
2082
|
+
* 0-based byte column offset of the call site or import declaration.
|
|
2083
|
+
*/
|
|
2084
|
+
col: number
|
|
2085
|
+
/**
|
|
2086
|
+
* Name of the rule pack that declared the matching rule.
|
|
2087
|
+
*/
|
|
2088
|
+
pack: string
|
|
2089
|
+
/**
|
|
2090
|
+
* Id of the matching rule inside the pack. `pack` plus `rule_id` is the
|
|
2091
|
+
* finding's policy identity.
|
|
2092
|
+
*/
|
|
2093
|
+
rule_id: string
|
|
2094
|
+
kind: PolicyRuleKind
|
|
2095
|
+
/**
|
|
2096
|
+
* What matched: the written callee path for `banned-call` (e.g.
|
|
2097
|
+
* `cp.exec`), or the raw import specifier for `banned-import` (e.g.
|
|
2098
|
+
* `moment/locale/nl`).
|
|
2099
|
+
*/
|
|
2100
|
+
matched: string
|
|
2101
|
+
severity: PolicyViolationSeverity
|
|
2102
|
+
/**
|
|
2103
|
+
* The rule's author-provided message, when set.
|
|
2104
|
+
*/
|
|
2105
|
+
message?: (string | null)
|
|
2106
|
+
/**
|
|
2107
|
+
* Suggested next steps.
|
|
2108
|
+
*/
|
|
2109
|
+
actions: IssueAction[]
|
|
2110
|
+
/**
|
|
2111
|
+
* Set by the audit pass when this finding is introduced relative to
|
|
2112
|
+
* the merge-base.
|
|
2113
|
+
*/
|
|
2114
|
+
introduced?: (AuditIntroduced | null)
|
|
2115
|
+
}
|
|
1840
2116
|
/**
|
|
1841
2117
|
* A suppression comment or JSDoc tag that no longer matches any issue.
|
|
1842
2118
|
*/
|
|
@@ -2170,73 +2446,6 @@ exceeded: boolean
|
|
|
2170
2446
|
*/
|
|
2171
2447
|
reason?: (string | null)
|
|
2172
2448
|
}
|
|
2173
|
-
/**
|
|
2174
|
-
* Metric and rule definitions emitted under `_meta` when `--explain` is
|
|
2175
|
-
* passed (always present in MCP responses). Helps AI agents and CI systems
|
|
2176
|
-
* interpret metric values without re-reading the docs site.
|
|
2177
|
-
*/
|
|
2178
|
-
export interface Meta {
|
|
2179
|
-
/**
|
|
2180
|
-
* URL to the documentation page for this command.
|
|
2181
|
-
*/
|
|
2182
|
-
docs?: (string | null)
|
|
2183
|
-
/**
|
|
2184
|
-
* Per-field definitions for envelope fields and action payload fields.
|
|
2185
|
-
*/
|
|
2186
|
-
field_definitions?: {
|
|
2187
|
-
[k: string]: string
|
|
2188
|
-
}
|
|
2189
|
-
/**
|
|
2190
|
-
* Per-metric definitions: name, description, range, interpretation.
|
|
2191
|
-
*/
|
|
2192
|
-
metrics?: {
|
|
2193
|
-
[k: string]: MetaMetric
|
|
2194
|
-
}
|
|
2195
|
-
/**
|
|
2196
|
-
* Per-rule definitions for check command output.
|
|
2197
|
-
*/
|
|
2198
|
-
rules?: {
|
|
2199
|
-
[k: string]: MetaRule
|
|
2200
|
-
}
|
|
2201
|
-
}
|
|
2202
|
-
/**
|
|
2203
|
-
* Single-metric definition inside [`Meta::metrics`].
|
|
2204
|
-
*/
|
|
2205
|
-
export interface MetaMetric {
|
|
2206
|
-
/**
|
|
2207
|
-
* Human-readable metric name.
|
|
2208
|
-
*/
|
|
2209
|
-
name?: (string | null)
|
|
2210
|
-
/**
|
|
2211
|
-
* What this metric measures and how it is computed.
|
|
2212
|
-
*/
|
|
2213
|
-
description?: (string | null)
|
|
2214
|
-
/**
|
|
2215
|
-
* Valid value range (e.g., `"[0, 100]"`).
|
|
2216
|
-
*/
|
|
2217
|
-
range?: (string | null)
|
|
2218
|
-
/**
|
|
2219
|
-
* How to read the value (e.g., `"lower is better"`).
|
|
2220
|
-
*/
|
|
2221
|
-
interpretation?: (string | null)
|
|
2222
|
-
}
|
|
2223
|
-
/**
|
|
2224
|
-
* Single-rule definition inside [`Meta::rules`].
|
|
2225
|
-
*/
|
|
2226
|
-
export interface MetaRule {
|
|
2227
|
-
/**
|
|
2228
|
-
* Human-readable rule name.
|
|
2229
|
-
*/
|
|
2230
|
-
name?: (string | null)
|
|
2231
|
-
/**
|
|
2232
|
-
* What this rule detects.
|
|
2233
|
-
*/
|
|
2234
|
-
description?: (string | null)
|
|
2235
|
-
/**
|
|
2236
|
-
* URL to the rule documentation.
|
|
2237
|
-
*/
|
|
2238
|
-
docs?: (string | null)
|
|
2239
|
-
}
|
|
2240
2449
|
/**
|
|
2241
2450
|
* Wire-shape payload for `fallow dupes --format json` (the body that
|
|
2242
2451
|
* flattens into [`crate::output_envelope::DupesOutput`] and is also
|
|
@@ -2777,7 +2986,7 @@ severity_high_count: number
|
|
|
2777
2986
|
severity_moderate_count: number
|
|
2778
2987
|
}
|
|
2779
2988
|
/**
|
|
2780
|
-
* Project-wide vital signs
|
|
2989
|
+
* Project-wide vital signs , a fixed set of metrics for trend tracking.
|
|
2781
2990
|
*
|
|
2782
2991
|
* Metrics are `Option` when the data source was not available in the current run
|
|
2783
2992
|
* (e.g., `duplication_pct` is `None` unless the duplication pipeline was run,
|
|
@@ -3318,7 +3527,7 @@ coverage_percent: number
|
|
|
3318
3527
|
trace_count: number
|
|
3319
3528
|
/**
|
|
3320
3529
|
* Days of observation covered by the supplied dump (Phase 2 local analysis
|
|
3321
|
-
* emits 0
|
|
3530
|
+
* emits 0 , set by the beacon/cloud in Phase 3+).
|
|
3322
3531
|
*/
|
|
3323
3532
|
period_days: number
|
|
3324
3533
|
/**
|
|
@@ -3780,6 +3989,14 @@ complex_functions?: EvidenceFunction[]
|
|
|
3780
3989
|
* Files forming the import cycle (populated for `BreakCircularDependency` targets).
|
|
3781
3990
|
*/
|
|
3782
3991
|
cycle_path?: string[]
|
|
3992
|
+
/**
|
|
3993
|
+
* Files that directly import this target, with imported and local symbols.
|
|
3994
|
+
*/
|
|
3995
|
+
direct_callers?: DirectCallerEvidence[]
|
|
3996
|
+
/**
|
|
3997
|
+
* Other duplicate-code instances that share a clone group with this target.
|
|
3998
|
+
*/
|
|
3999
|
+
clone_siblings?: CloneSiblingEvidence[]
|
|
3783
4000
|
}
|
|
3784
4001
|
/**
|
|
3785
4002
|
* A function referenced in target evidence.
|
|
@@ -3798,6 +4015,57 @@ line: number
|
|
|
3798
4015
|
*/
|
|
3799
4016
|
cognitive: number
|
|
3800
4017
|
}
|
|
4018
|
+
/**
|
|
4019
|
+
* A direct importer referenced in target evidence.
|
|
4020
|
+
*/
|
|
4021
|
+
export interface DirectCallerEvidence {
|
|
4022
|
+
/**
|
|
4023
|
+
* File that directly imports the target.
|
|
4024
|
+
*/
|
|
4025
|
+
path: string
|
|
4026
|
+
/**
|
|
4027
|
+
* Symbols imported from the target by this file.
|
|
4028
|
+
*/
|
|
4029
|
+
symbols?: DirectCallerSymbolEvidence[]
|
|
4030
|
+
}
|
|
4031
|
+
/**
|
|
4032
|
+
* Symbol details for a direct importer.
|
|
4033
|
+
*/
|
|
4034
|
+
export interface DirectCallerSymbolEvidence {
|
|
4035
|
+
/**
|
|
4036
|
+
* Imported binding name.
|
|
4037
|
+
*/
|
|
4038
|
+
imported: string
|
|
4039
|
+
/**
|
|
4040
|
+
* Local binding name in the importing file.
|
|
4041
|
+
*/
|
|
4042
|
+
local: string
|
|
4043
|
+
/**
|
|
4044
|
+
* Whether the import is type-only.
|
|
4045
|
+
*/
|
|
4046
|
+
type_only: boolean
|
|
4047
|
+
}
|
|
4048
|
+
/**
|
|
4049
|
+
* A duplicate-code sibling referenced in target evidence.
|
|
4050
|
+
*/
|
|
4051
|
+
export interface CloneSiblingEvidence {
|
|
4052
|
+
/**
|
|
4053
|
+
* File containing the sibling clone instance.
|
|
4054
|
+
*/
|
|
4055
|
+
path: string
|
|
4056
|
+
/**
|
|
4057
|
+
* 1-based start line of the sibling clone.
|
|
4058
|
+
*/
|
|
4059
|
+
start_line: number
|
|
4060
|
+
/**
|
|
4061
|
+
* 1-based end line of the sibling clone.
|
|
4062
|
+
*/
|
|
4063
|
+
end_line: number
|
|
4064
|
+
/**
|
|
4065
|
+
* Stable duplicate-group handle, matching `dupes --trace dup:<id>`.
|
|
4066
|
+
*/
|
|
4067
|
+
fingerprint: string
|
|
4068
|
+
}
|
|
3801
4069
|
/**
|
|
3802
4070
|
* Suggested action attached to a [`RefactoringTarget`].
|
|
3803
4071
|
*
|
|
@@ -4731,6 +4999,25 @@ re_export_cycles?: ReExportCycleFinding[]
|
|
|
4731
4999
|
* array natively.
|
|
4732
5000
|
*/
|
|
4733
5001
|
boundary_violations?: BoundaryViolationFinding[]
|
|
5002
|
+
/**
|
|
5003
|
+
* Files that matched no architecture boundary zone while
|
|
5004
|
+
* `boundaries.coverage.requireAllFiles` was enabled.
|
|
5005
|
+
*/
|
|
5006
|
+
boundary_coverage_violations?: BoundaryCoverageViolationFinding[]
|
|
5007
|
+
/**
|
|
5008
|
+
* Calls from zoned files to callees forbidden for that zone via
|
|
5009
|
+
* `boundaries.calls.forbidden`. Wrapped in
|
|
5010
|
+
* [`BoundaryCallViolationFinding`] so each entry carries a typed
|
|
5011
|
+
* `actions` array natively.
|
|
5012
|
+
*/
|
|
5013
|
+
boundary_call_violations?: BoundaryCallViolationFinding[]
|
|
5014
|
+
/**
|
|
5015
|
+
* Banned calls and banned imports matched by declarative rule packs
|
|
5016
|
+
* (`rulePacks` config). Wrapped in [`PolicyViolationFinding`] so each
|
|
5017
|
+
* entry carries a typed `actions` array natively. Each finding carries
|
|
5018
|
+
* its effective per-rule severity.
|
|
5019
|
+
*/
|
|
5020
|
+
policy_violations?: PolicyViolationFinding[]
|
|
4734
5021
|
/**
|
|
4735
5022
|
* Suppression comments or JSDoc tags that no longer match any issue.
|
|
4736
5023
|
*/
|
|
@@ -4782,6 +5069,7 @@ export interface ImpactReport {
|
|
|
4782
5069
|
schema_version: ImpactReportSchemaVersion
|
|
4783
5070
|
enabled: boolean
|
|
4784
5071
|
record_count: number
|
|
5072
|
+
_meta?: (Meta | null)
|
|
4785
5073
|
first_recorded?: (string | null)
|
|
4786
5074
|
/**
|
|
4787
5075
|
* Git SHA of the most recent recorded run, so a consumer can tell which
|
|
@@ -4883,6 +5171,13 @@ timestamp: string
|
|
|
4883
5171
|
*/
|
|
4884
5172
|
export interface SecurityOutput {
|
|
4885
5173
|
schema_version: SecuritySchemaVersion
|
|
5174
|
+
version: ToolVersion
|
|
5175
|
+
elapsed_ms: ElapsedMs
|
|
5176
|
+
config: SecurityOutputConfig
|
|
5177
|
+
/**
|
|
5178
|
+
* Security-specific rule and field metadata, emitted with `--explain`.
|
|
5179
|
+
*/
|
|
5180
|
+
_meta?: (Meta | null)
|
|
4886
5181
|
/**
|
|
4887
5182
|
* Gate verdict, present only when `--gate <mode>` was set (issue #886).
|
|
4888
5183
|
* Emitted on pass too (`verdict: "pass"`, `new_count: 0`) so consumers
|
|
@@ -4912,6 +5207,34 @@ unresolved_edge_files: number
|
|
|
4912
5207
|
* here is NOT a clean bill.
|
|
4913
5208
|
*/
|
|
4914
5209
|
unresolved_callee_sites: number
|
|
5210
|
+
/**
|
|
5211
|
+
* Bounded diagnostics for unresolved callee blind spots.
|
|
5212
|
+
*/
|
|
5213
|
+
unresolved_callee_diagnostics?: (SecurityUnresolvedCalleeDiagnostics | null)
|
|
5214
|
+
}
|
|
5215
|
+
/**
|
|
5216
|
+
* Allowlisted config context for `fallow security --format json`.
|
|
5217
|
+
*/
|
|
5218
|
+
export interface SecurityOutputConfig {
|
|
5219
|
+
rules: SecurityOutputRulesConfig
|
|
5220
|
+
/**
|
|
5221
|
+
* `security.categories.include` from config. `null` means unset, `[]`
|
|
5222
|
+
* means explicitly empty.
|
|
5223
|
+
*/
|
|
5224
|
+
categories_include: (string[] | null)
|
|
5225
|
+
/**
|
|
5226
|
+
* `security.categories.exclude` from config. `null` means unset, `[]`
|
|
5227
|
+
* means explicitly empty.
|
|
5228
|
+
*/
|
|
5229
|
+
categories_exclude: (string[] | null)
|
|
5230
|
+
}
|
|
5231
|
+
export interface SecurityOutputRulesConfig {
|
|
5232
|
+
security_client_server_leak: SecurityRuleSeverityConfig
|
|
5233
|
+
security_sink: SecurityRuleSeverityConfig
|
|
5234
|
+
}
|
|
5235
|
+
export interface SecurityRuleSeverityConfig {
|
|
5236
|
+
configured: Severity
|
|
5237
|
+
effective: Severity
|
|
4915
5238
|
}
|
|
4916
5239
|
/**
|
|
4917
5240
|
* The `gate` block on `SecurityOutput`, present only when `--gate <mode>` ran.
|
|
@@ -4921,7 +5244,7 @@ export interface SecurityGate {
|
|
|
4921
5244
|
mode: SecurityGateMode
|
|
4922
5245
|
verdict: SecurityGateVerdict
|
|
4923
5246
|
/**
|
|
4924
|
-
* Number of candidates
|
|
5247
|
+
* Number of candidates matching the selected gate mode.
|
|
4925
5248
|
*/
|
|
4926
5249
|
new_count: number
|
|
4927
5250
|
}
|
|
@@ -5192,6 +5515,12 @@ cwe?: (number | null)
|
|
|
5192
5515
|
* `None` for `client-server-leak` and matches that name no callee.
|
|
5193
5516
|
*/
|
|
5194
5517
|
callee?: (string | null)
|
|
5518
|
+
/**
|
|
5519
|
+
* URL construction shape for SSRF and open-redirect style candidates when
|
|
5520
|
+
* fallow can classify whether the origin is fixed or dynamic. Absent for
|
|
5521
|
+
* non-URL sinks and unclassified URL expressions.
|
|
5522
|
+
*/
|
|
5523
|
+
url_shape?: (SecurityUrlShape | null)
|
|
5195
5524
|
}
|
|
5196
5525
|
/**
|
|
5197
5526
|
* The boundary slot of a [`SecurityCandidate`]: which structural boundaries the
|
|
@@ -5377,6 +5706,155 @@ col: number
|
|
|
5377
5706
|
*/
|
|
5378
5707
|
callee: string
|
|
5379
5708
|
}
|
|
5709
|
+
/**
|
|
5710
|
+
* Bounded unresolved-callee diagnostics for `fallow security --format json`.
|
|
5711
|
+
*/
|
|
5712
|
+
export interface SecurityUnresolvedCalleeDiagnostics {
|
|
5713
|
+
/**
|
|
5714
|
+
* Deterministic sample rows, capped by `sample_limit`.
|
|
5715
|
+
*/
|
|
5716
|
+
sampled: SecurityUnresolvedCalleeSample[]
|
|
5717
|
+
/**
|
|
5718
|
+
* Files with the most unresolved callees, capped by `top_files_limit`.
|
|
5719
|
+
*/
|
|
5720
|
+
top_files: SecurityUnresolvedCalleeTopFile[]
|
|
5721
|
+
/**
|
|
5722
|
+
* Full count by unresolved-callee reason, sorted by count then reason.
|
|
5723
|
+
*/
|
|
5724
|
+
by_reason: SecurityUnresolvedCalleeReasonCount[]
|
|
5725
|
+
/**
|
|
5726
|
+
* Maximum number of sample rows emitted.
|
|
5727
|
+
*/
|
|
5728
|
+
sample_limit: number
|
|
5729
|
+
/**
|
|
5730
|
+
* Maximum number of top-file rows emitted.
|
|
5731
|
+
*/
|
|
5732
|
+
top_files_limit: number
|
|
5733
|
+
}
|
|
5734
|
+
/**
|
|
5735
|
+
* One sampled unresolved-callee row.
|
|
5736
|
+
*/
|
|
5737
|
+
export interface SecurityUnresolvedCalleeSample {
|
|
5738
|
+
/**
|
|
5739
|
+
* Project-relative source path.
|
|
5740
|
+
*/
|
|
5741
|
+
path: string
|
|
5742
|
+
/**
|
|
5743
|
+
* 1-based source line.
|
|
5744
|
+
*/
|
|
5745
|
+
line: number
|
|
5746
|
+
/**
|
|
5747
|
+
* 0-based byte column.
|
|
5748
|
+
*/
|
|
5749
|
+
col: number
|
|
5750
|
+
reason: SkippedSecurityCalleeReason
|
|
5751
|
+
expression_kind: SkippedSecurityCalleeExpressionKind
|
|
5752
|
+
}
|
|
5753
|
+
/**
|
|
5754
|
+
* Count of unresolved callees in one file.
|
|
5755
|
+
*/
|
|
5756
|
+
export interface SecurityUnresolvedCalleeTopFile {
|
|
5757
|
+
/**
|
|
5758
|
+
* Project-relative source path.
|
|
5759
|
+
*/
|
|
5760
|
+
path: string
|
|
5761
|
+
/**
|
|
5762
|
+
* Number of unresolved callees in this file.
|
|
5763
|
+
*/
|
|
5764
|
+
count: number
|
|
5765
|
+
}
|
|
5766
|
+
/**
|
|
5767
|
+
* Count of unresolved callees for one reason.
|
|
5768
|
+
*/
|
|
5769
|
+
export interface SecurityUnresolvedCalleeReasonCount {
|
|
5770
|
+
reason: SkippedSecurityCalleeReason
|
|
5771
|
+
/**
|
|
5772
|
+
* Number of unresolved callees with this reason.
|
|
5773
|
+
*/
|
|
5774
|
+
count: number
|
|
5775
|
+
}
|
|
5776
|
+
/**
|
|
5777
|
+
* Compact `fallow security --summary --format json` payload. Uses the same
|
|
5778
|
+
* `kind: "security"` discriminator as the full payload, but omits candidate
|
|
5779
|
+
* arrays and exposes only aggregate counts.
|
|
5780
|
+
*/
|
|
5781
|
+
export interface SecuritySummaryOutput {
|
|
5782
|
+
schema_version: SecuritySchemaVersion
|
|
5783
|
+
version: ToolVersion
|
|
5784
|
+
elapsed_ms: ElapsedMs
|
|
5785
|
+
config: SecurityOutputConfig
|
|
5786
|
+
/**
|
|
5787
|
+
* Security-specific rule and field metadata, emitted with `--explain`.
|
|
5788
|
+
*/
|
|
5789
|
+
_meta?: (Meta | null)
|
|
5790
|
+
/**
|
|
5791
|
+
* Gate verdict, present only when `--gate <mode>` was set.
|
|
5792
|
+
*/
|
|
5793
|
+
gate?: (SecurityGate | null)
|
|
5794
|
+
summary: SecuritySummary
|
|
5795
|
+
}
|
|
5796
|
+
/**
|
|
5797
|
+
* Aggregate counts for `fallow security --summary --format json`.
|
|
5798
|
+
*/
|
|
5799
|
+
export interface SecuritySummary {
|
|
5800
|
+
/**
|
|
5801
|
+
* Number of security candidates after all filters, gates, and scopes.
|
|
5802
|
+
*/
|
|
5803
|
+
security_findings: number
|
|
5804
|
+
by_severity: SecuritySeverityCounts
|
|
5805
|
+
/**
|
|
5806
|
+
* Finding counts by catalogue category, or by kind for findings without a
|
|
5807
|
+
* catalogue category.
|
|
5808
|
+
*/
|
|
5809
|
+
by_category: {
|
|
5810
|
+
[k: string]: number
|
|
5811
|
+
}
|
|
5812
|
+
by_reachability: SecurityReachabilityCounts
|
|
5813
|
+
by_runtime_state: SecurityRuntimeStateCounts
|
|
5814
|
+
/**
|
|
5815
|
+
* Number of client files whose dynamic imports could not be followed.
|
|
5816
|
+
*/
|
|
5817
|
+
unresolved_edge_files: number
|
|
5818
|
+
/**
|
|
5819
|
+
* Number of sink-shaped callees that could not be statically flattened.
|
|
5820
|
+
*/
|
|
5821
|
+
unresolved_callee_sites: number
|
|
5822
|
+
/**
|
|
5823
|
+
* Number of attack-surface entries included in the prepared full output.
|
|
5824
|
+
*/
|
|
5825
|
+
attack_surface_entries: number
|
|
5826
|
+
}
|
|
5827
|
+
/**
|
|
5828
|
+
* Fixed severity counters for summary JSON.
|
|
5829
|
+
*/
|
|
5830
|
+
export interface SecuritySeverityCounts {
|
|
5831
|
+
high: number
|
|
5832
|
+
medium: number
|
|
5833
|
+
low: number
|
|
5834
|
+
}
|
|
5835
|
+
/**
|
|
5836
|
+
* Fixed reachability counters for summary JSON.
|
|
5837
|
+
*/
|
|
5838
|
+
export interface SecurityReachabilityCounts {
|
|
5839
|
+
entry_reachable: number
|
|
5840
|
+
untrusted_source_reachable: number
|
|
5841
|
+
arg_level: number
|
|
5842
|
+
module_level: number
|
|
5843
|
+
crosses_boundary: number
|
|
5844
|
+
source_backed: number
|
|
5845
|
+
}
|
|
5846
|
+
/**
|
|
5847
|
+
* Fixed runtime coverage counters for summary JSON.
|
|
5848
|
+
*/
|
|
5849
|
+
export interface SecurityRuntimeStateCounts {
|
|
5850
|
+
runtime_hot: number
|
|
5851
|
+
runtime_cold: number
|
|
5852
|
+
never_executed: number
|
|
5853
|
+
low_traffic: number
|
|
5854
|
+
coverage_unavailable: number
|
|
5855
|
+
runtime_unknown: number
|
|
5856
|
+
not_collected: number
|
|
5857
|
+
}
|
|
5380
5858
|
/**
|
|
5381
5859
|
* Bare `fallow --format json` envelope.
|
|
5382
5860
|
*/
|
|
@@ -5393,6 +5871,7 @@ export interface CombinedMeta {
|
|
|
5393
5871
|
check?: (Meta | null)
|
|
5394
5872
|
dupes?: (Meta | null)
|
|
5395
5873
|
health?: (Meta | null)
|
|
5874
|
+
telemetry?: (TelemetryMeta | null)
|
|
5396
5875
|
}
|
|
5397
5876
|
/**
|
|
5398
5877
|
* Single CodeClimate-compatible issue inside [`CodeClimateOutput`].
|