fallow 2.101.0 → 2.102.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fallow",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.102.0",
|
|
4
4
|
"description": "Deterministic codebase intelligence for TypeScript and JavaScript. Quality, risk, architecture, dependencies, duplication, and safe cleanup evidence for humans, CI, and agents. Optional runtime intelligence layer (Fallow Runtime) adds production execution evidence. Rust-native, sub-second, zero-config framework support.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -80,16 +80,16 @@
|
|
|
80
80
|
"detect-libc": "2.1.2"
|
|
81
81
|
},
|
|
82
82
|
"devDependencies": {
|
|
83
|
-
"@tanstack/intent": "0.
|
|
83
|
+
"@tanstack/intent": "0.1.1"
|
|
84
84
|
},
|
|
85
85
|
"optionalDependencies": {
|
|
86
|
-
"@fallow-cli/darwin-arm64": "2.
|
|
87
|
-
"@fallow-cli/darwin-x64": "2.
|
|
88
|
-
"@fallow-cli/linux-x64-gnu": "2.
|
|
89
|
-
"@fallow-cli/linux-arm64-gnu": "2.
|
|
90
|
-
"@fallow-cli/linux-x64-musl": "2.
|
|
91
|
-
"@fallow-cli/linux-arm64-musl": "2.
|
|
92
|
-
"@fallow-cli/win32-arm64-msvc": "2.
|
|
93
|
-
"@fallow-cli/win32-x64-msvc": "2.
|
|
86
|
+
"@fallow-cli/darwin-arm64": "2.102.0",
|
|
87
|
+
"@fallow-cli/darwin-x64": "2.102.0",
|
|
88
|
+
"@fallow-cli/linux-x64-gnu": "2.102.0",
|
|
89
|
+
"@fallow-cli/linux-arm64-gnu": "2.102.0",
|
|
90
|
+
"@fallow-cli/linux-x64-musl": "2.102.0",
|
|
91
|
+
"@fallow-cli/linux-arm64-musl": "2.102.0",
|
|
92
|
+
"@fallow-cli/win32-arm64-msvc": "2.102.0",
|
|
93
|
+
"@fallow-cli/win32-x64-msvc": "2.102.0"
|
|
94
94
|
}
|
|
95
95
|
}
|
package/skills/fallow/SKILL.md
CHANGED
|
@@ -13,7 +13,6 @@ metadata:
|
|
|
13
13
|
Codebase intelligence for JavaScript and TypeScript. The free static layer reports quality, changed-code risk, cleanup opportunities, circular dependencies, code duplication, complexity hotspots, architecture boundary violations, feature flag patterns, and opt-in security candidates. Runtime coverage merges production execution data into the same `fallow health` report for hot-path review, cold-path deletion confidence, and stale-flag evidence, with a single local capture available by default and continuous/cloud runtime monitoring available as an optional mode. 122 framework plugins, zero configuration, sub-second static analysis.
|
|
14
14
|
|
|
15
15
|
## When to Use
|
|
16
|
-
|
|
17
16
|
- Finding cleanup opportunities (unused files, exports, types, enum/class members)
|
|
18
17
|
- Finding unused or unlisted dependencies
|
|
19
18
|
- Detecting code duplication and clones
|
|
@@ -32,7 +31,6 @@ Codebase intelligence for JavaScript and TypeScript. The free static layer repor
|
|
|
32
31
|
- Reviewing what fallow has surfaced over time (`fallow impact`)
|
|
33
32
|
|
|
34
33
|
## When NOT to Use
|
|
35
|
-
|
|
36
34
|
- Runtime error analysis or debugging
|
|
37
35
|
- Type checking (use `tsc` for that)
|
|
38
36
|
- Linting style or formatting issues (use ESLint, Biome, Prettier)
|
|
@@ -96,6 +94,7 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
|
|
|
96
94
|
| `dead-code` | Dead code analysis (`check` is an alias) | `--unused-exports`, `--changed-since`, `--changed-workspaces`, `--production`, `--file`, `--include-entry-exports`, `--stale-suppressions`, `--ci`, `--group-by`, `--summary`, `--fail-on-regression`, `--tolerance`, `--regression-baseline`, `--save-regression-baseline` |
|
|
97
95
|
| `watch` | Watch for changes and re-run analysis | `--no-clear` |
|
|
98
96
|
| `inspect` | Compose one evidence bundle for a file or exported symbol | `--file <path>`, `--symbol <file>:<export>` |
|
|
97
|
+
| `trace` | Trace a symbol's call chain (best-effort, syntactic; OFF the ranked path) | `symbol`, `--callers`, `--callees`, `--depth` |
|
|
99
98
|
| `fix` | Auto-remove unused exports/deps | `--dry-run`, `--yes` (required in non-TTY) |
|
|
100
99
|
| `init` | Generate config file, AGENTS.md agent guide, or pre-commit hook | `--toml`, `--agents`, `--hooks`, `--branch` |
|
|
101
100
|
| `hooks` | Inspect, install, or remove fallow-managed Git and agent hooks | `status`, `install --target git`, `install --target agent`, `uninstall --target git`, `uninstall --target agent` |
|
|
@@ -112,6 +111,7 @@ Route by intent before reaching for the big analysis commands. Same matrix as `f
|
|
|
112
111
|
| `flags` | Detect feature flag patterns (env vars, SDK calls, config objects) | `--top` |
|
|
113
112
|
| `explain` | Explain one issue type without running analysis | `<issue-type>`, `--format json` |
|
|
114
113
|
| `audit` | Combined dead-code + complexity + duplication for changed files | `--base`, `--gate`, `--production`, `--production-dead-code`, `--production-health`, `--production-dupes`, `--workspace`, `--changed-workspaces`, `--ci`, `--fail-on-issues`, `--explain`, `--explain-skipped`, `--dead-code-baseline`, `--health-baseline`, `--dupes-baseline`, `--max-crap`, `--coverage`, `--coverage-root`, `--include-entry-exports` |
|
|
114
|
+
| `decision-surface` | Surface the consequential structural DECISIONS a change embeds (the apex of the review brief), each framed as a judgment question with the routed expert to ask | `--max-decisions` |
|
|
115
115
|
| `impact` | Show what fallow has done for you: how many issues it is surfacing, the trend since the last recorded run, and how many commits it contained at the pre-commit gate | `--all`, `--sort`, `--limit` |
|
|
116
116
|
| `security` | Surface opt-in local security candidates for agent verification (not confirmed vulnerabilities). Rule families include the graph rule `client-server-leak`, a data-driven `tainted-sink` catalogue, and the include-required `hardcoded-secret` category for provider-prefix credentials and high-entropy literals assigned to secret-shaped identifiers. Most catalogue rows require non-literal input; narrowly literal-aware rows flag deterministic unsafe literals. Rules default off; suppress a file with `// fallow-ignore-file security-sink`; scope categories with `security.categories`. Add project-local request object names with `security.requestReceivers`; it extends the built-in `req` / `request` / `ctx` / `context` / `event` allowlist for HTTP `query`, `params`, and `body` reads. `hardcoded-secret` runs only when listed in `security.categories.include`. | `--format human\|json\|sarif`, `--changed-since`, `--file`, `--diff-file`, `--workspace`, `--changed-workspaces`, `--surface`, `--ci`, `--fail-on-issues`, `--sarif-file`, `--summary` |
|
|
117
117
|
| `schema` | Dump CLI definition as JSON | |
|
|
@@ -211,6 +211,7 @@ When using fallow via MCP (`fallow-mcp`), the following tools are available:
|
|
|
211
211
|
| `get_importance` | runtime-coverage | freemium | `coverage`, `group_by` | Runtime-context slice for production-importance review. Same params as `check_runtime_coverage`; read `runtime_coverage.importance` for stable `fallow:importance:<hash>` IDs, invocations, cyclomatic complexity, owner count, 0-100 score, and templated reason. |
|
|
212
212
|
| `get_cleanup_candidates` | runtime-coverage | freemium | `coverage`, `group_by` | Runtime-context slice for cleanup review. Same params as `check_runtime_coverage`; read `runtime_coverage.findings` for `safe_to_delete`, `review_required`, `low_traffic`, and `coverage_unavailable`. |
|
|
213
213
|
| `audit` | analysis | free | `gate`, `base`, `max_crap`, `coverage`, `runtime_coverage` | Combined dead-code + complexity + duplication for changed files, returns verdict. Set `gate` to `"new-only"` or `"all"`. Optional `runtime_coverage` (V8 dir / V8 JSON / Istanbul JSON) folds runtime findings into the same call; `min_invocations_hot` tunes the hot-path threshold (default 100). Runtime evidence appears under the audit `complexity` sub-result, including `coverage_intelligence` when combined evidence yields actionable recommendations. |
|
|
214
|
+
| `decision_surface` | analysis | free | `base`, `max_decisions`, `workspace` | Surface the few consequential structural decisions a change embeds (coupling, public API, dependency), each as a judgment question with the routed expert; ranked, capped, and signal_id-anchored |
|
|
214
215
|
| `fallow_explain` | introspection | free | `issue_type` | Explain one issue type without running analysis. Required `issue_type`; returns rationale, examples, fix guidance, and docs URL |
|
|
215
216
|
| `fix_preview` | fix | free | `no_create_config` | Dry-run auto-fix preview |
|
|
216
217
|
| `fix_apply` | fix | free | `no_create_config` | Apply auto-fixes (destructive) |
|
|
@@ -45,6 +45,7 @@ Analyzes the project for unused files, exports, dependencies, types, members, an
|
|
|
45
45
|
| `--trace` | `string` | - | Trace export usage chain |
|
|
46
46
|
| `--trace-file` | `string` | - | Show all edges for a file |
|
|
47
47
|
| `--trace-dependency` | `string` | - | Trace where a dependency is used |
|
|
48
|
+
| `--impact-closure` | `string` | - | Compute the impact closure for a file (the transitive affected-but-not-in-diff set + coordination gap). Walks reverse-deps and re-export chains; powers the `inspect_target` MCP tool |
|
|
48
49
|
| `--top` | `string` | - | Show only the top N items per category |
|
|
49
50
|
| `--file` | `string` | - | Scope output to specific files. Only issues in the specified files are reported. Project-wide dependency issues are suppressed. Warns on non-existent paths. Useful for lint-staged |
|
|
50
51
|
|
|
@@ -505,7 +506,7 @@ fallow health --format json --quiet --trend
|
|
|
505
506
|
{
|
|
506
507
|
"kind": "health",
|
|
507
508
|
"schema_version": 7,
|
|
508
|
-
"version": "2.
|
|
509
|
+
"version": "2.102.0",
|
|
509
510
|
"elapsed_ms": 32,
|
|
510
511
|
"summary": {
|
|
511
512
|
"files_analyzed": 482,
|
|
@@ -828,6 +829,11 @@ Audits changed files for dead code, complexity, and duplication. Returns a verdi
|
|
|
828
829
|
| `--runtime-coverage` | `string` | - | Paid runtime-coverage sidecar input. Accepts a V8 directory, a single V8 JSON file, or an Istanbul coverage map JSON. Spawns the `fallow-cov` sidecar as part of the audit pipeline so the `hot-path-touched` verdict surfaces alongside dead-code and complexity findings without requiring a second `fallow health` invocation in CI. License-gated; the verdict is informational (no exit code change) until a future `--gate hot-path-touched` knob lands |
|
|
829
830
|
| `--min-invocations-hot` | `string` | `100` | Threshold for hot-path classification, forwarded to the sidecar when `--runtime-coverage` is set |
|
|
830
831
|
| `--gate-marker` | `string` | - | Internal marker identifying a gate run (e.g. `pre-commit`), set by the generated git hook so Fallow Impact can record a containment event when the gate blocks then clears. Hidden; never changes the verdict, exit code, or output |
|
|
832
|
+
| `--brief` | `bool` | `false` | Render the deterministic review brief instead of the gating audit report. The brief answers "where do I look?" rather than "will CI block this?", runs the same analysis, and ALWAYS exits 0 (the verdict is carried informationally). Implied by `fallow review`. Orthogonal to `--format` |
|
|
833
|
+
| `--max-decisions` | `string` | `4` | Cap on the number of consequential structural decisions surfaced in the review brief's decision surface (the working-memory limit). Default 4; clamped to the 3-5 band (4 plus or minus 1). Only consulted on the brief path |
|
|
834
|
+
| `--walkthrough-guide` | `bool` | `false` | Emit the agent-contract WALKTHROUGH GUIDE: the current digest (brief + decision surface), the review direction, the JSON schema the agent must return, and a deterministic graph-snapshot hash pinned into the digest. The digest is built from the graph only (PR prose is never folded in, so it is injection-resistant). Implies the brief; always exits 0. A thin agent skill calls this to fetch the current guide, produces judgment JSON, then reopens with `--walkthrough-file` |
|
|
835
|
+
| `--walkthrough-file` | `string` | - | Ingest an agent's judgment JSON and POST-VALIDATE it against the LIVE graph. Rejects any judgment whose `signal_id` fallow did not emit (anti-hallucination); refuses the whole payload as stale when the echoed graph-snapshot hash no longer matches (the tree moved). The verifier is the graph, not a second model. Implies the brief; always exits 0. The agent's free-text framing is fenced as non-deterministic and never gates or auto-posts |
|
|
836
|
+
| `--show-deprioritized` | `bool` | `false` | Expand the de-prioritized units in the review brief's weighted focus map ("show me what you de-prioritized"). The `deprioritized` escape-hatch list is ALWAYS present in `--format json` regardless; this flag only re-expands the collapse-by-default human focus render. Only consulted on the brief path |
|
|
831
837
|
|
|
832
838
|
Common global flags for this command: [`--format`](#global-flags), [`--quiet`](#global-flags), [`--changed-since`](#global-flags), [`--diff-file`](#global-flags), [`--diff-stdin`](#global-flags), [`--workspace`](#global-flags), [`--changed-workspaces`](#global-flags), [`--group-by`](#global-flags), [`--output-file`](#global-flags).
|
|
833
839
|
<!-- generated:flags:audit:end -->
|
|
@@ -892,7 +898,7 @@ fallow audit \
|
|
|
892
898
|
{
|
|
893
899
|
"kind": "audit",
|
|
894
900
|
"schema_version": 7,
|
|
895
|
-
"version": "2.
|
|
901
|
+
"version": "2.102.0",
|
|
896
902
|
"command": "audit",
|
|
897
903
|
"verdict": "fail",
|
|
898
904
|
"changed_files_count": 12,
|
|
@@ -967,7 +973,7 @@ fallow flags --format json --quiet --workspace my-package
|
|
|
967
973
|
```json
|
|
968
974
|
{
|
|
969
975
|
"schema_version": 7,
|
|
970
|
-
"version": "2.
|
|
976
|
+
"version": "2.102.0",
|
|
971
977
|
"elapsed_ms": 116,
|
|
972
978
|
"feature_flags": [],
|
|
973
979
|
"total_flags": 0
|
|
@@ -1067,7 +1073,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1067
1073
|
{
|
|
1068
1074
|
"kind": "security",
|
|
1069
1075
|
"schema_version": "4",
|
|
1070
|
-
"version": "2.
|
|
1076
|
+
"version": "2.102.0",
|
|
1071
1077
|
"elapsed_ms": 42,
|
|
1072
1078
|
"config": {
|
|
1073
1079
|
"rules": {
|
|
@@ -1096,7 +1102,7 @@ fallow security --gate newly-reachable --changed-since origin/main
|
|
|
1096
1102
|
{
|
|
1097
1103
|
"kind": "security",
|
|
1098
1104
|
"schema_version": "4",
|
|
1099
|
-
"version": "2.
|
|
1105
|
+
"version": "2.102.0",
|
|
1100
1106
|
"elapsed_ms": 42,
|
|
1101
1107
|
"config": {
|
|
1102
1108
|
"rules": {
|
|
@@ -1762,7 +1768,7 @@ The HTTP layer mirrors the bash `gh_api_retry` / `curl_retry` helpers: `FALLOW_A
|
|
|
1762
1768
|
{
|
|
1763
1769
|
"kind": "dead-code",
|
|
1764
1770
|
"schema_version": 7,
|
|
1765
|
-
"version": "2.
|
|
1771
|
+
"version": "2.102.0",
|
|
1766
1772
|
"elapsed_ms": 45,
|
|
1767
1773
|
"total_issues": 12,
|
|
1768
1774
|
"entry_points": {
|
|
@@ -1922,7 +1928,7 @@ When `--baseline` is used in combined output, the JSON includes a `baseline_delt
|
|
|
1922
1928
|
{
|
|
1923
1929
|
"kind": "dupes",
|
|
1924
1930
|
"schema_version": 7,
|
|
1925
|
-
"version": "2.
|
|
1931
|
+
"version": "2.102.0",
|
|
1926
1932
|
"elapsed_ms": 82,
|
|
1927
1933
|
"total_clones": 15,
|
|
1928
1934
|
"total_lines_duplicated": 230,
|
|
@@ -1966,11 +1972,11 @@ When running `fallow` with no subcommand (all analyses), the JSON output combine
|
|
|
1966
1972
|
{
|
|
1967
1973
|
"kind": "combined",
|
|
1968
1974
|
"schema_version": 7,
|
|
1969
|
-
"version": "2.
|
|
1975
|
+
"version": "2.102.0",
|
|
1970
1976
|
"elapsed_ms": 159,
|
|
1971
1977
|
"check": {
|
|
1972
1978
|
"schema_version": 7,
|
|
1973
|
-
"version": "2.
|
|
1979
|
+
"version": "2.102.0",
|
|
1974
1980
|
"elapsed_ms": 45,
|
|
1975
1981
|
"total_issues": 12,
|
|
1976
1982
|
"unused_files": [],
|
|
@@ -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
|
|
@@ -763,6 +769,44 @@ export type SecurityVerifierVerdictStatus = ("survivor" | "dismissed" | "needs-h
|
|
|
763
769
|
* The `fallow security blind-spots --format json` schema version.
|
|
764
770
|
*/
|
|
765
771
|
export type SecurityBlindSpotsSchemaVersion = "1"
|
|
772
|
+
/**
|
|
773
|
+
* Independently-versioned wire-version newtype for the brief envelope.
|
|
774
|
+
* Serializes as the integer `REVIEW_BRIEF_SCHEMA_VERSION`.
|
|
775
|
+
*/
|
|
776
|
+
export type ReviewBriefSchemaVersion = number
|
|
777
|
+
/**
|
|
778
|
+
* Coarse risk classification for a changeset, a pure function of the change
|
|
779
|
+
* size (file count plus, once threaded, net lines).
|
|
780
|
+
*/
|
|
781
|
+
export type RiskClass = ("low" | "medium" | "high")
|
|
782
|
+
/**
|
|
783
|
+
* Suggested reviewer effort, a pure function of [`RiskClass`].
|
|
784
|
+
*/
|
|
785
|
+
export type ReviewEffort = ("glance" | "review" | "deep_dive")
|
|
786
|
+
/**
|
|
787
|
+
* The focus label for a review unit. EXACTLY two variants: `Skip` is NOT
|
|
788
|
+
* representable, so the type system is the guarantee that free mode never emits
|
|
789
|
+
* a `skip` label (safe explicit-skip is paid, runtime-backed only). Mirrors
|
|
790
|
+
* the decision surface's "cut category not representable" structural posture.
|
|
791
|
+
*/
|
|
792
|
+
export type FocusLabel = ("review-here" | "not-prioritized")
|
|
793
|
+
/**
|
|
794
|
+
* A per-unit confidence flag. The EXACT panel-decided strings: a dynamically-
|
|
795
|
+
* wired or re-export-heavy unit carries one so its static-reachability signal is
|
|
796
|
+
* not trusted as complete (the anti-silent-de-prioritization guard). The flag
|
|
797
|
+
* NEVER lowers the score; it is advisory provenance.
|
|
798
|
+
*/
|
|
799
|
+
export type ConfidenceFlag = ("dynamic-dispatch" | "re-export-indirection")
|
|
800
|
+
/**
|
|
801
|
+
* The category of a single weakening signal.
|
|
802
|
+
*/
|
|
803
|
+
export type WeakeningKind = ("test-weakened" | "threshold-lowered" | "suppression-added" | "security-check-removed")
|
|
804
|
+
/**
|
|
805
|
+
* The exactly-three shippable decision categories (the SOLID-3). No cut category
|
|
806
|
+
* (abstraction / deletion / convention / irreversibility) is representable: this
|
|
807
|
+
* enum is the structural guarantee that confirmed-noise categories never ship.
|
|
808
|
+
*/
|
|
809
|
+
export type DecisionCategory = ("coupling-boundary" | "public-api-contract" | "dependency")
|
|
766
810
|
/**
|
|
767
811
|
* Discriminator value for [`CodeClimateIssue::kind`].
|
|
768
812
|
*/
|
|
@@ -2882,11 +2926,15 @@ export interface UnrenderedComponentFinding {
|
|
|
2882
2926
|
*/
|
|
2883
2927
|
path: string
|
|
2884
2928
|
/**
|
|
2885
|
-
* The component name
|
|
2929
|
+
* The component name. For `"vue"` / `"svelte"` / `"astro"` this is the SFC
|
|
2930
|
+
* file stem (PascalCase); for `"angular"` it is the component class name; for
|
|
2931
|
+
* `"lit"` it is the registered custom-element TAG (e.g. `x-foo`), not a file
|
|
2932
|
+
* stem. Use `path` to anchor the file across all frameworks.
|
|
2886
2933
|
*/
|
|
2887
2934
|
component_name: string
|
|
2888
2935
|
/**
|
|
2889
|
-
* Which framework this component belongs to: `"vue"
|
|
2936
|
+
* Which framework this component belongs to: `"vue"`, `"svelte"`, `"astro"`,
|
|
2937
|
+
* `"angular"`, or `"lit"`.
|
|
2890
2938
|
*/
|
|
2891
2939
|
framework: string
|
|
2892
2940
|
/**
|
|
@@ -6453,6 +6501,14 @@ dead_code: InspectEvidenceSection
|
|
|
6453
6501
|
duplication: InspectEvidenceSection
|
|
6454
6502
|
complexity: InspectEvidenceSection
|
|
6455
6503
|
security: InspectEvidenceSection
|
|
6504
|
+
impact_closure: InspectEvidenceSection
|
|
6505
|
+
/**
|
|
6506
|
+
* OPT-IN symbol-level call chain. Present only when `--symbol-chain` was
|
|
6507
|
+
* requested AND the target is a SYMBOL (best-effort, syntactic, OFF the
|
|
6508
|
+
* ranked path). `None` (omitted) by default: symbol-level chains are
|
|
6509
|
+
* best-effort and not part of the trusted ranked evidence.
|
|
6510
|
+
*/
|
|
6511
|
+
symbol_chain?: (InspectEvidenceSection | null)
|
|
6456
6512
|
}
|
|
6457
6513
|
export interface InspectEvidenceSection {
|
|
6458
6514
|
status: InspectSectionStatus
|
|
@@ -8439,6 +8495,659 @@ dupes?: (Meta | null)
|
|
|
8439
8495
|
health?: (Meta | null)
|
|
8440
8496
|
telemetry?: (TelemetryMeta | null)
|
|
8441
8497
|
}
|
|
8498
|
+
/**
|
|
8499
|
+
* The full `fallow audit --brief --format json` envelope. Carries the
|
|
8500
|
+
* informational verdict, the triage and graph-facts orientation stages, plus
|
|
8501
|
+
* the reused "subtract" section (the same dead-code / duplication / complexity
|
|
8502
|
+
* payload `fallow audit --format json` emits).
|
|
8503
|
+
*/
|
|
8504
|
+
export interface ReviewBriefOutput {
|
|
8505
|
+
schema_version: ReviewBriefSchemaVersion
|
|
8506
|
+
/**
|
|
8507
|
+
* Fallow CLI version that produced this output.
|
|
8508
|
+
*/
|
|
8509
|
+
version: string
|
|
8510
|
+
/**
|
|
8511
|
+
* Command discriminator singleton: always `"audit-brief"`.
|
|
8512
|
+
*/
|
|
8513
|
+
command: string
|
|
8514
|
+
triage: DiffTriage
|
|
8515
|
+
graph_facts: GraphFacts
|
|
8516
|
+
partition: PartitionFacts
|
|
8517
|
+
impact_closure: ImpactClosureFacts
|
|
8518
|
+
focus: FocusMap
|
|
8519
|
+
deltas: ReviewDeltas
|
|
8520
|
+
/**
|
|
8521
|
+
* 6.F, headline: reviewer-private weakening signals (tests
|
|
8522
|
+
* removed/skipped, thresholds lowered, suppressions added, security steps
|
|
8523
|
+
* removed). Advisory, never gates, never auto-posted.
|
|
8524
|
+
*/
|
|
8525
|
+
weakening: WeakeningSignal[]
|
|
8526
|
+
routing: RoutingFacts
|
|
8527
|
+
decisions: DecisionSurface
|
|
8528
|
+
}
|
|
8529
|
+
/**
|
|
8530
|
+
* Stage 0 of the brief: triage facts derived purely from the diff size.
|
|
8531
|
+
*
|
|
8532
|
+
* `hunks` and `net_lines` are `None` in v1: the file-level audit does not yet
|
|
8533
|
+
* thread a `DiffIndex` (from `report/ci/diff_filter.rs`). They populate later,
|
|
8534
|
+
* on `--diff-file` / `--diff-stdin`, without a schema bump.
|
|
8535
|
+
*/
|
|
8536
|
+
export interface DiffTriage {
|
|
8537
|
+
/**
|
|
8538
|
+
* Number of changed files in the audit scope.
|
|
8539
|
+
*/
|
|
8540
|
+
files: number
|
|
8541
|
+
/**
|
|
8542
|
+
* Number of diff hunks. `None` in v1 (no diff index threaded yet).
|
|
8543
|
+
*/
|
|
8544
|
+
hunks?: (number | null)
|
|
8545
|
+
/**
|
|
8546
|
+
* Net added-minus-removed lines. `None` in v1 (no diff index threaded yet).
|
|
8547
|
+
*/
|
|
8548
|
+
net_lines?: (number | null)
|
|
8549
|
+
risk_class: RiskClass
|
|
8550
|
+
review_effort: ReviewEffort
|
|
8551
|
+
}
|
|
8552
|
+
/**
|
|
8553
|
+
* Stage 1 of the brief: graph-derived orientation facts.
|
|
8554
|
+
*
|
|
8555
|
+
* `boundaries_touched` is derived from the run's boundary-violation zones;
|
|
8556
|
+
* `reachable_from` is populated by the impact closure (the affected-not-shown
|
|
8557
|
+
* set: modules the changed code is reachable from / affects, none in the diff).
|
|
8558
|
+
* `exports_added` / `api_width_delta` stay honestly stubbed (`0`) until the
|
|
8559
|
+
* export-surface delta lands. The fields are present and correctly typed so
|
|
8560
|
+
* values fill in later without a schema bump.
|
|
8561
|
+
*/
|
|
8562
|
+
export interface GraphFacts {
|
|
8563
|
+
/**
|
|
8564
|
+
* Number of exports added by the changeset. Stubbed to `0` in v1.
|
|
8565
|
+
*/
|
|
8566
|
+
exports_added: number
|
|
8567
|
+
/**
|
|
8568
|
+
* Change in public API width (added minus removed exports). Stubbed to `0`
|
|
8569
|
+
* in v1.
|
|
8570
|
+
*/
|
|
8571
|
+
api_width_delta: number
|
|
8572
|
+
/**
|
|
8573
|
+
* Root-relative paths of modules the changed code is reachable from / affects
|
|
8574
|
+
* (the impact closure's affected-but-not-in-diff set), deduped and sorted.
|
|
8575
|
+
* Empty when no graph was retained or nothing depends on the changed files.
|
|
8576
|
+
*/
|
|
8577
|
+
reachable_from: string[]
|
|
8578
|
+
/**
|
|
8579
|
+
* Architecture boundary zones touched by the changeset, deduped and sorted.
|
|
8580
|
+
* Derived from the run's boundary-violation findings.
|
|
8581
|
+
*/
|
|
8582
|
+
boundaries_touched: string[]
|
|
8583
|
+
}
|
|
8584
|
+
/**
|
|
8585
|
+
* Stage 2 of the brief: the partition + order. The changed files split into
|
|
8586
|
+
* coherent BY-MODULE units (the only byte-identical-deterministic clustering
|
|
8587
|
+
* definition straight from the graph), plus a dependency-sensible review ORDER
|
|
8588
|
+
* over those units (definitions before consumers, mechanical/leaf units last,
|
|
8589
|
+
* ties broken by the path sort). Stage 2 sits UNDER the decision surface as a
|
|
8590
|
+
* drill-down; it is the backbone the directed-review loop hands the agent.
|
|
8591
|
+
*
|
|
8592
|
+
* Feature-cluster and concern partitioning are deferred (they need scoring
|
|
8593
|
+
* heuristics whose tie-breaks are a fresh nondeterminism surface).
|
|
8594
|
+
*/
|
|
8595
|
+
export interface PartitionFacts {
|
|
8596
|
+
/**
|
|
8597
|
+
* The by-module units, sorted by module directory. Empty when no graph was
|
|
8598
|
+
* retained or no changed file maps to a known module.
|
|
8599
|
+
*/
|
|
8600
|
+
units: ReviewUnitFact[]
|
|
8601
|
+
/**
|
|
8602
|
+
* The dependency-sensible review order: module-directory strings,
|
|
8603
|
+
* definitions before consumers, mechanical/leaf units last. A permutation of
|
|
8604
|
+
* the `units` module directories.
|
|
8605
|
+
*/
|
|
8606
|
+
order: string[]
|
|
8607
|
+
}
|
|
8608
|
+
/**
|
|
8609
|
+
* One review unit: a coherent by-module cluster of the changed set.
|
|
8610
|
+
*/
|
|
8611
|
+
export interface ReviewUnitFact {
|
|
8612
|
+
/**
|
|
8613
|
+
* The module directory the unit covers (root-relative, forward-slashed).
|
|
8614
|
+
* The empty string is the repository-root group.
|
|
8615
|
+
*/
|
|
8616
|
+
module_dir: string
|
|
8617
|
+
/**
|
|
8618
|
+
* The changed files in this unit, path-sorted.
|
|
8619
|
+
*/
|
|
8620
|
+
files: string[]
|
|
8621
|
+
}
|
|
8622
|
+
/**
|
|
8623
|
+
* Stage 3 of the brief: the impact closure. The transitive
|
|
8624
|
+
* affected-but-not-in-diff set plus the coordination gap. The differentiator a
|
|
8625
|
+
* diff tool fundamentally cannot do, because it has no graph.
|
|
8626
|
+
*
|
|
8627
|
+
* Honest scope (ADR-001, syntactic): the coordination gap is an attention
|
|
8628
|
+
* pointer at the exact inter-module failure mode, NOT a correctness proof.
|
|
8629
|
+
*/
|
|
8630
|
+
export interface ImpactClosureFacts {
|
|
8631
|
+
/**
|
|
8632
|
+
* Root-relative paths transitively affected by the changeset (reverse-deps +
|
|
8633
|
+
* re-export chains) that are NOT in the diff, deduped and sorted.
|
|
8634
|
+
*/
|
|
8635
|
+
affected_not_shown: string[]
|
|
8636
|
+
/**
|
|
8637
|
+
* Coordination gaps: a changed file exports a contract consumed by a module
|
|
8638
|
+
* absent from the diff. One entry per (changed file, consumer) pair.
|
|
8639
|
+
*/
|
|
8640
|
+
coordination_gap: CoordinationGapFact[]
|
|
8641
|
+
}
|
|
8642
|
+
/**
|
|
8643
|
+
* One coordination-gap entry: a changed file exports symbols consumed by a
|
|
8644
|
+
* `consumer_file` that is NOT in the diff. Deduped per (changed, consumer) pair
|
|
8645
|
+
* (firing-precision rule R2).
|
|
8646
|
+
*/
|
|
8647
|
+
export interface CoordinationGapFact {
|
|
8648
|
+
/**
|
|
8649
|
+
* Root-relative path of the changed file whose contract is consumed elsewhere.
|
|
8650
|
+
*/
|
|
8651
|
+
changed_file: string
|
|
8652
|
+
/**
|
|
8653
|
+
* Root-relative path of the consumer module that is NOT in the diff.
|
|
8654
|
+
*/
|
|
8655
|
+
consumer_file: string
|
|
8656
|
+
/**
|
|
8657
|
+
* The exported symbol names the consumer references, sorted.
|
|
8658
|
+
*/
|
|
8659
|
+
consumed_symbols: string[]
|
|
8660
|
+
/**
|
|
8661
|
+
* Honest scope note: this is a syntactic attention pointer, not a proof.
|
|
8662
|
+
*/
|
|
8663
|
+
note: string
|
|
8664
|
+
}
|
|
8665
|
+
/**
|
|
8666
|
+
* The weighted focus map: the ranked `review-here` units plus the FULL
|
|
8667
|
+
* `deprioritized` escape-hatch list, so nothing is hidden.
|
|
8668
|
+
*
|
|
8669
|
+
* Completeness invariant (the escape-hatch done-condition): the two lists
|
|
8670
|
+
* partition the unit set, so `review_here.len() + deprioritized.len()` equals
|
|
8671
|
+
* the total unit count by construction.
|
|
8672
|
+
*/
|
|
8673
|
+
export interface FocusMap {
|
|
8674
|
+
/**
|
|
8675
|
+
* Units labeled `review-here`, ranked by composite score (descending), ties
|
|
8676
|
+
* broken by path for determinism.
|
|
8677
|
+
*/
|
|
8678
|
+
review_here: FocusUnit[]
|
|
8679
|
+
/**
|
|
8680
|
+
* EVERY `not-prioritized` unit (the escape hatch). Always present and fully
|
|
8681
|
+
* enumerated so a reviewer can always "show me what you de-prioritized"; the
|
|
8682
|
+
* human brief collapses it by default and re-expands under
|
|
8683
|
+
* `--show-deprioritized`.
|
|
8684
|
+
*/
|
|
8685
|
+
deprioritized: FocusUnit[]
|
|
8686
|
+
}
|
|
8687
|
+
/**
|
|
8688
|
+
* One review unit on the focus map: its file, composite score, label, human
|
|
8689
|
+
* reason, and any confidence flags.
|
|
8690
|
+
*/
|
|
8691
|
+
export interface FocusUnit {
|
|
8692
|
+
/**
|
|
8693
|
+
* Root-relative path of the changed file this unit covers.
|
|
8694
|
+
*/
|
|
8695
|
+
file: string
|
|
8696
|
+
score: FocusScore
|
|
8697
|
+
label: FocusLabel
|
|
8698
|
+
/**
|
|
8699
|
+
* A human-readable reason for the label, built from the present signals.
|
|
8700
|
+
*/
|
|
8701
|
+
reason: string
|
|
8702
|
+
/**
|
|
8703
|
+
* Confidence flags (advisory; never lower the score). Sorted, deduped.
|
|
8704
|
+
*/
|
|
8705
|
+
confidence?: ConfidenceFlag[]
|
|
8706
|
+
}
|
|
8707
|
+
/**
|
|
8708
|
+
* The composite attention score, with the four deterministic component
|
|
8709
|
+
* sub-scores kept on the wire so the runtime seam can re-weight `total`
|
|
8710
|
+
* without recomputing the signals.
|
|
8711
|
+
*/
|
|
8712
|
+
export interface FocusScore {
|
|
8713
|
+
/**
|
|
8714
|
+
* Fan-in/out blast-radius component.
|
|
8715
|
+
*/
|
|
8716
|
+
fan_io: number
|
|
8717
|
+
/**
|
|
8718
|
+
* Security source -> sink taint-touch component (0 until a security pass is
|
|
8719
|
+
* threaded onto the brief path; the seam is built and tested).
|
|
8720
|
+
*/
|
|
8721
|
+
security_taint: number
|
|
8722
|
+
/**
|
|
8723
|
+
* Risk-zone component (boundary / public-API / security-sensitive).
|
|
8724
|
+
*/
|
|
8725
|
+
risk_zone: number
|
|
8726
|
+
/**
|
|
8727
|
+
* Change-shape component (new/widened export, signature change proxy).
|
|
8728
|
+
*/
|
|
8729
|
+
change_shape: number
|
|
8730
|
+
/**
|
|
8731
|
+
* The summed total. The paid runtime layer multiplies a runtime hot/cold weight in here.
|
|
8732
|
+
*/
|
|
8733
|
+
total: number
|
|
8734
|
+
}
|
|
8735
|
+
/**
|
|
8736
|
+
* Diff-aware deterministic deltas (6.A), framed new-vs-pre-existing against
|
|
8737
|
+
* the audit base snapshot. Each entry is a brief summary/verdict line.
|
|
8738
|
+
*
|
|
8739
|
+
* `public_api` is batch-consolidated to ONE decision per change (rule R1):
|
|
8740
|
+
* the `added` list carries the introduced public-export keys as evidence, but a
|
|
8741
|
+
* reviewer reads "the public surface widened by N", never one decision per
|
|
8742
|
+
* symbol.
|
|
8743
|
+
*/
|
|
8744
|
+
export interface ReviewDeltas {
|
|
8745
|
+
/**
|
|
8746
|
+
* Cross-zone boundary EDGES introduced vs base (R2 first-edge-only: one per
|
|
8747
|
+
* `<from_zone>-><to_zone>` pair, never per import). New-vs-pre-existing.
|
|
8748
|
+
*/
|
|
8749
|
+
boundary_introduced: string[]
|
|
8750
|
+
/**
|
|
8751
|
+
* Circular dependencies introduced vs base (canonical file-set keys).
|
|
8752
|
+
*/
|
|
8753
|
+
cycle_introduced: string[]
|
|
8754
|
+
/**
|
|
8755
|
+
* Exports-aware public-API surface delta: the public-export keys
|
|
8756
|
+
* (`<rel_path>::<name>`) added vs base, resolved through `package.json`
|
|
8757
|
+
* `exports` + re-export reachability. A symbol re-exported only through an
|
|
8758
|
+
* internal barrel NOT in `exports` is absent here (zero delta); one
|
|
8759
|
+
* reachable through an `exports` path is present (exactly one).
|
|
8760
|
+
*/
|
|
8761
|
+
public_api_added: string[]
|
|
8762
|
+
}
|
|
8763
|
+
/**
|
|
8764
|
+
* One weakening signal: a category, the file it was detected in, and a short
|
|
8765
|
+
* human-readable evidence string. Reviewer-private; never gates.
|
|
8766
|
+
*/
|
|
8767
|
+
export interface WeakeningSignal {
|
|
8768
|
+
kind: WeakeningKind
|
|
8769
|
+
/**
|
|
8770
|
+
* Root-relative path of the changed file the signal was detected in.
|
|
8771
|
+
*/
|
|
8772
|
+
file: string
|
|
8773
|
+
/**
|
|
8774
|
+
* Short evidence string (e.g. the offending token or the threshold delta).
|
|
8775
|
+
*/
|
|
8776
|
+
evidence: string
|
|
8777
|
+
}
|
|
8778
|
+
/**
|
|
8779
|
+
* The full routing section: one unit per changed source file with a routable
|
|
8780
|
+
* signal. Files with no ownership signal are omitted (no noise).
|
|
8781
|
+
*/
|
|
8782
|
+
export interface RoutingFacts {
|
|
8783
|
+
/**
|
|
8784
|
+
* Per-changed-file routing units, sorted by file path.
|
|
8785
|
+
*/
|
|
8786
|
+
units: RoutingUnit[]
|
|
8787
|
+
}
|
|
8788
|
+
/**
|
|
8789
|
+
* One routed unit (a changed file) with its experts and bus-factor flag.
|
|
8790
|
+
*/
|
|
8791
|
+
export interface RoutingUnit {
|
|
8792
|
+
/**
|
|
8793
|
+
* Root-relative path of the changed file.
|
|
8794
|
+
*/
|
|
8795
|
+
file: string
|
|
8796
|
+
/**
|
|
8797
|
+
* The routed expert(s): the CODEOWNERS declared owner when present, else the
|
|
8798
|
+
* top git-blame / recency contributor; empty when no signal is available.
|
|
8799
|
+
*/
|
|
8800
|
+
expert: string[]
|
|
8801
|
+
/**
|
|
8802
|
+
* Whether the only qualified owner is a single contributor (bus-factor-1):
|
|
8803
|
+
* a knowledge-concentration risk worth a second reviewer.
|
|
8804
|
+
*/
|
|
8805
|
+
bus_factor_one?: boolean
|
|
8806
|
+
}
|
|
8807
|
+
/**
|
|
8808
|
+
* The ranked, capped decision surface plus the set of signal_ids the
|
|
8809
|
+
* deterministic layer emitted (the anti-hallucination allowlist).
|
|
8810
|
+
*/
|
|
8811
|
+
export interface DecisionSurface {
|
|
8812
|
+
/**
|
|
8813
|
+
* Up to `cap` ranked decisions, highest consequence first.
|
|
8814
|
+
*/
|
|
8815
|
+
decisions: Decision[]
|
|
8816
|
+
/**
|
|
8817
|
+
* Present when more than `cap` decisions were extracted.
|
|
8818
|
+
*/
|
|
8819
|
+
truncated?: (TruncationNote | null)
|
|
8820
|
+
/**
|
|
8821
|
+
* Every signal_id the deterministic layer emitted, INCLUDING those whose
|
|
8822
|
+
* decision was collapsed below the cap or suppressed. The anti-hallucination
|
|
8823
|
+
* allowlist: an agent decision whose id is absent is rejected.
|
|
8824
|
+
*/
|
|
8825
|
+
emitted_signal_ids: string[]
|
|
8826
|
+
}
|
|
8827
|
+
/**
|
|
8828
|
+
* One consequential structural decision, framed as a judgment question for a
|
|
8829
|
+
* human with taste, anchored to a fallow-emitted signal.
|
|
8830
|
+
*/
|
|
8831
|
+
export interface Decision {
|
|
8832
|
+
/**
|
|
8833
|
+
* Deterministic anchor to the fallow-emitted candidate this decision frames.
|
|
8834
|
+
* `accept_signal_id` rejects any id not in the emitted set.
|
|
8835
|
+
*/
|
|
8836
|
+
signal_id: string
|
|
8837
|
+
category: DecisionCategory
|
|
8838
|
+
/**
|
|
8839
|
+
* The decision framed as a judgment question for the human.
|
|
8840
|
+
*/
|
|
8841
|
+
question: string
|
|
8842
|
+
/**
|
|
8843
|
+
* Root-relative file the decision is anchored at (for suppression + routing).
|
|
8844
|
+
*/
|
|
8845
|
+
anchor_file: string
|
|
8846
|
+
/**
|
|
8847
|
+
* 1-based anchor line, when the underlying signal carries one (0 = file head).
|
|
8848
|
+
*/
|
|
8849
|
+
anchor_line: number
|
|
8850
|
+
/**
|
|
8851
|
+
* The raw fallow-emitted candidate key the `signal_id` hashes (the evidence).
|
|
8852
|
+
*/
|
|
8853
|
+
signal_key: string
|
|
8854
|
+
/**
|
|
8855
|
+
* The `signal_id` this decision WOULD have had before any rename in this
|
|
8856
|
+
* change (the anchor file's pre-rename path). Present only when the anchor was
|
|
8857
|
+
* renamed. A review-memory layer carries a dismissal across a `git mv`: if
|
|
8858
|
+
* `previous_signal_id` was dismissed in an earlier PR, treat this decision as
|
|
8859
|
+
* dismissed too. Keeps `signal_id` itself exact + deterministic.
|
|
8860
|
+
*/
|
|
8861
|
+
previous_signal_id?: (string | null)
|
|
8862
|
+
/**
|
|
8863
|
+
* Blast radius: count of modules affected beyond the diff by this decision.
|
|
8864
|
+
*/
|
|
8865
|
+
blast: number
|
|
8866
|
+
/**
|
|
8867
|
+
* `blast * reversibility_weight`: the rank key (sorted descending).
|
|
8868
|
+
*/
|
|
8869
|
+
consequence: number
|
|
8870
|
+
/**
|
|
8871
|
+
* The routed expert(s) to ask, from ownership routing. Empty when no
|
|
8872
|
+
* ownership signal is available for the anchor file.
|
|
8873
|
+
*/
|
|
8874
|
+
expert: string[]
|
|
8875
|
+
/**
|
|
8876
|
+
* Whether the anchor file's only qualified owner is one person (bus-factor-1).
|
|
8877
|
+
*/
|
|
8878
|
+
bus_factor_one?: boolean
|
|
8879
|
+
/**
|
|
8880
|
+
* Honest per-decision count: in-repo modules OUTSIDE the diff that already
|
|
8881
|
+
* depend on this decision's anchor. This is the DISPLAY number (taste
|
|
8882
|
+
* ownership: the human reads reversibility from the count itself), distinct
|
|
8883
|
+
* from `blast` (the project-wide proxy used only for ranking). Never a door
|
|
8884
|
+
* label. Internal-only by construction, so it cannot see a published library's
|
|
8885
|
+
* external consumers; the public-API trade-off clause names that risk in prose.
|
|
8886
|
+
*/
|
|
8887
|
+
internal_consumer_count: number
|
|
8888
|
+
/**
|
|
8889
|
+
* The named structural sacrifice this change makes, stated as a fact, never a
|
|
8890
|
+
* recommendation (e.g. "Couples `app` to `infra`; 4 in-repo modules already
|
|
8891
|
+
* depend on this anchor."). A sibling fact to `question`; it never tells the
|
|
8892
|
+
* human what to choose.
|
|
8893
|
+
*/
|
|
8894
|
+
tradeoff: string
|
|
8895
|
+
}
|
|
8896
|
+
/**
|
|
8897
|
+
* A note for the decisions collapsed below the cap.
|
|
8898
|
+
*/
|
|
8899
|
+
export interface TruncationNote {
|
|
8900
|
+
/**
|
|
8901
|
+
* How many decisions were collapsed below the cap.
|
|
8902
|
+
*/
|
|
8903
|
+
collapsed: number
|
|
8904
|
+
/**
|
|
8905
|
+
* Human-readable collapse reason.
|
|
8906
|
+
*/
|
|
8907
|
+
reason: string
|
|
8908
|
+
}
|
|
8909
|
+
/**
|
|
8910
|
+
* The `fallow review --walkthrough-guide` envelope: the current digest + schema
|
|
8911
|
+
* the agent fetches. The tool owns this; the skill stays thin (it fetches this
|
|
8912
|
+
* rather than embedding a frozen copy). Always emitted with exit 0.
|
|
8913
|
+
*/
|
|
8914
|
+
export interface WalkthroughGuide {
|
|
8915
|
+
schema_version: ReviewBriefSchemaVersion
|
|
8916
|
+
/**
|
|
8917
|
+
* Fallow CLI version that produced this guide.
|
|
8918
|
+
*/
|
|
8919
|
+
version: string
|
|
8920
|
+
/**
|
|
8921
|
+
* Command discriminator singleton: always `"review-walkthrough-guide"`.
|
|
8922
|
+
*/
|
|
8923
|
+
command: string
|
|
8924
|
+
/**
|
|
8925
|
+
* The deterministic graph-snapshot hash pinned into the digest. The agent
|
|
8926
|
+
* echoes it back; a mismatch on reentry refuses the payload as stale.
|
|
8927
|
+
*/
|
|
8928
|
+
graph_snapshot_hash: string
|
|
8929
|
+
digest: ReviewBriefOutput
|
|
8930
|
+
direction: ReviewDirection
|
|
8931
|
+
/**
|
|
8932
|
+
* The per-hunk change anchors: one stable id per changed region. An agent
|
|
8933
|
+
* may cite a `change_anchor` as a judgment anchor in addition to an emitted
|
|
8934
|
+
* `signal_id`, so a trade-off about a changed region with no graph finding
|
|
8935
|
+
* can still anchor (and be post-validated) rather than hallucinate.
|
|
8936
|
+
*/
|
|
8937
|
+
change_anchors: ChangeAnchor[]
|
|
8938
|
+
agent_schema: AgentSchema
|
|
8939
|
+
/**
|
|
8940
|
+
* The injection-resistance note (digest is graph-only; PR prose untrusted).
|
|
8941
|
+
*/
|
|
8942
|
+
injection_note: string
|
|
8943
|
+
}
|
|
8944
|
+
/**
|
|
8945
|
+
* The review direction artifact: the order to review in, the coherent units,
|
|
8946
|
+
* and per-unit concern lens + out-of-diff + expert. A minimal projection of the
|
|
8947
|
+
* EXISTING graph facts (routing units + impact closure); the full weighted-focus
|
|
8948
|
+
* engine is a later epic. Graph-derived only (injection-resistant).
|
|
8949
|
+
*/
|
|
8950
|
+
export interface ReviewDirection {
|
|
8951
|
+
/**
|
|
8952
|
+
* The dependency-sensible review order: unit file paths, units carrying
|
|
8953
|
+
* out-of-diff consumers first (review the load-bearing definitions before
|
|
8954
|
+
* the mechanical units).
|
|
8955
|
+
*/
|
|
8956
|
+
order: string[]
|
|
8957
|
+
/**
|
|
8958
|
+
* The coherent review units, in `order`.
|
|
8959
|
+
*/
|
|
8960
|
+
units: DirectionUnit[]
|
|
8961
|
+
}
|
|
8962
|
+
/**
|
|
8963
|
+
* One directed review unit projected from the graph: a file the change touches,
|
|
8964
|
+
* the concern to check, the out-of-diff consumers it must account for, and the
|
|
8965
|
+
* routed expert. Graph-derived only (routing + impact closure), NEVER from prose.
|
|
8966
|
+
*/
|
|
8967
|
+
export interface DirectionUnit {
|
|
8968
|
+
/**
|
|
8969
|
+
* Root-relative path of the unit to review.
|
|
8970
|
+
*/
|
|
8971
|
+
file: string
|
|
8972
|
+
/**
|
|
8973
|
+
* The concern lens the agent should check for this unit, derived from the
|
|
8974
|
+
* unit's risk signals (impact-closure consumers vs a plain touched file).
|
|
8975
|
+
*/
|
|
8976
|
+
concern_lens: string
|
|
8977
|
+
/**
|
|
8978
|
+
* Per-unit review-effort budget: the weighted-focus composite score for
|
|
8979
|
+
* this file. A cloud fan-out spends AI passes/verifiers PROPORTIONAL to this
|
|
8980
|
+
* (higher = review harder); a local single-agent loop can ignore it.
|
|
8981
|
+
*/
|
|
8982
|
+
scoring_budget: number
|
|
8983
|
+
/**
|
|
8984
|
+
* Root-relative paths of modules affected by this unit but NOT in the diff
|
|
8985
|
+
* (the out-of-diff context the agent must reason about).
|
|
8986
|
+
*/
|
|
8987
|
+
out_of_diff: string[]
|
|
8988
|
+
/**
|
|
8989
|
+
* The routed expert(s) to ask, from ownership routing.
|
|
8990
|
+
*/
|
|
8991
|
+
expert: string[]
|
|
8992
|
+
}
|
|
8993
|
+
/**
|
|
8994
|
+
* One stable per-hunk CHANGE ANCHOR: a changed region the agent may cite as a
|
|
8995
|
+
* judgment anchor IN ADDITION to a `signal_id`. Where a `signal_id` anchors a
|
|
8996
|
+
* graph FINDING ("fallow emitted this exact finding"), a change_anchor anchors
|
|
8997
|
+
* only a changed REGION ("fallow confirms this region changed") , a strictly
|
|
8998
|
+
* weaker guarantee, surfaced as `anchor_kind` on the accepted judgment so a
|
|
8999
|
+
* consumer can tell the two apart. Graph/diff-derived; NEVER from prose.
|
|
9000
|
+
*/
|
|
9001
|
+
export interface ChangeAnchor {
|
|
9002
|
+
/**
|
|
9003
|
+
* Stable, CONTENT-addressed id: `chg:<16-hex>` over the file path + the
|
|
9004
|
+
* normalized added text (line numbers are NOT hashed, so an edit above the
|
|
9005
|
+
* hunk or a whitespace-only change does not move the id).
|
|
9006
|
+
*/
|
|
9007
|
+
change_anchor: string
|
|
9008
|
+
/**
|
|
9009
|
+
* Root-relative path of the changed file.
|
|
9010
|
+
*/
|
|
9011
|
+
file: string
|
|
9012
|
+
/**
|
|
9013
|
+
* 1-based first line of the hunk in the head file (display/deep-link only;
|
|
9014
|
+
* NOT part of the id).
|
|
9015
|
+
*/
|
|
9016
|
+
start_line: number
|
|
9017
|
+
/**
|
|
9018
|
+
* Number of added lines in the hunk (display only; NOT part of the id).
|
|
9019
|
+
*/
|
|
9020
|
+
line_count: number
|
|
9021
|
+
/**
|
|
9022
|
+
* Rename-durable anchor: the id this same hunk would have had under the
|
|
9023
|
+
* pre-rename path. `None` unless the file was renamed in this change, so an
|
|
9024
|
+
* agent that cited the anchor before a `git mv` still resolves.
|
|
9025
|
+
*/
|
|
9026
|
+
previous_change_anchor?: (string | null)
|
|
9027
|
+
}
|
|
9028
|
+
/**
|
|
9029
|
+
* The shape the agent must return, embedded in the guide so a thin skill needs
|
|
9030
|
+
* no frozen copy. Documents the anchoring + staleness contract in the wire.
|
|
9031
|
+
*/
|
|
9032
|
+
export interface AgentSchema {
|
|
9033
|
+
/**
|
|
9034
|
+
* How the agent must structure each judgment: cite an emitted `signal_id`,
|
|
9035
|
+
* add free-text `framing` (non-deterministic, fenced), an optional `concern`.
|
|
9036
|
+
*/
|
|
9037
|
+
judgment_shape: string
|
|
9038
|
+
/**
|
|
9039
|
+
* The agent MUST echo this `graph_snapshot_hash` back in its JSON; a
|
|
9040
|
+
* mismatch on reentry REFUSES the payload as stale.
|
|
9041
|
+
*/
|
|
9042
|
+
echo_field: string
|
|
9043
|
+
/**
|
|
9044
|
+
* The constant naming the anti-hallucination rule.
|
|
9045
|
+
*/
|
|
9046
|
+
anchoring_rule: string
|
|
9047
|
+
}
|
|
9048
|
+
/**
|
|
9049
|
+
* The `fallow review --walkthrough-file` validation envelope: the result of
|
|
9050
|
+
* post-validating the agent's judgment against the live graph. Always exit 0.
|
|
9051
|
+
*/
|
|
9052
|
+
export interface WalkthroughValidation {
|
|
9053
|
+
schema_version: ReviewBriefSchemaVersion
|
|
9054
|
+
/**
|
|
9055
|
+
* Fallow CLI version that produced this validation.
|
|
9056
|
+
*/
|
|
9057
|
+
version: string
|
|
9058
|
+
/**
|
|
9059
|
+
* Command discriminator singleton: always `"review-walkthrough-validation"`.
|
|
9060
|
+
*/
|
|
9061
|
+
command: string
|
|
9062
|
+
/**
|
|
9063
|
+
* The current run's deterministic graph-snapshot hash.
|
|
9064
|
+
*/
|
|
9065
|
+
graph_snapshot_hash: string
|
|
9066
|
+
/**
|
|
9067
|
+
* `true` when the agent's echoed hash != the current hash (the tree moved):
|
|
9068
|
+
* the WHOLE payload is refused, `accepted` is empty.
|
|
9069
|
+
*/
|
|
9070
|
+
stale: boolean
|
|
9071
|
+
/**
|
|
9072
|
+
* Judgments that cite a real fallow-emitted signal, framing fenced.
|
|
9073
|
+
*/
|
|
9074
|
+
accepted: AcceptedJudgment[]
|
|
9075
|
+
/**
|
|
9076
|
+
* Judgments rejected (unanchored signal id, or all-rejected when stale).
|
|
9077
|
+
*/
|
|
9078
|
+
rejected: RejectedJudgment[]
|
|
9079
|
+
/**
|
|
9080
|
+
* Count of accepted judgments.
|
|
9081
|
+
*/
|
|
9082
|
+
accepted_count: number
|
|
9083
|
+
/**
|
|
9084
|
+
* Count of rejected judgments.
|
|
9085
|
+
*/
|
|
9086
|
+
rejected_count: number
|
|
9087
|
+
/**
|
|
9088
|
+
* Count of accepted judgments whose `signal_id` resolved against the live
|
|
9089
|
+
* allowlist. Zero unanchored when this equals `accepted_count` and there are
|
|
9090
|
+
* no rejections (the clean done-condition).
|
|
9091
|
+
*/
|
|
9092
|
+
unanchored_count: number
|
|
9093
|
+
}
|
|
9094
|
+
/**
|
|
9095
|
+
* One accepted judgment: the real anchored signal passed through with the
|
|
9096
|
+
* agent's framing FENCED as non-deterministic.
|
|
9097
|
+
*/
|
|
9098
|
+
export interface AcceptedJudgment {
|
|
9099
|
+
/**
|
|
9100
|
+
* The fallow-emitted `signal_id` (verified against the allowlist). Empty
|
|
9101
|
+
* when this judgment was anchored by a `change_anchor` instead.
|
|
9102
|
+
*/
|
|
9103
|
+
signal_id: string
|
|
9104
|
+
/**
|
|
9105
|
+
* The fallow-emitted `change_anchor` (verified against the allowlist). Empty
|
|
9106
|
+
* when this judgment was anchored by a `signal_id`.
|
|
9107
|
+
*/
|
|
9108
|
+
change_anchor: string
|
|
9109
|
+
/**
|
|
9110
|
+
* Which anchor resolved: `"signal"` (a graph FINDING, the strong anchor) or
|
|
9111
|
+
* `"change"` (a changed REGION only, the weaker anchor). Lets a consumer
|
|
9112
|
+
* distinguish a finding-anchored judgment from a region-anchored one rather
|
|
9113
|
+
* than collapsing both into one accepted bucket.
|
|
9114
|
+
*/
|
|
9115
|
+
anchor_kind: string
|
|
9116
|
+
/**
|
|
9117
|
+
* The agent's framing, FENCED: this is non-deterministic agent prose.
|
|
9118
|
+
*/
|
|
9119
|
+
agent_framing: string
|
|
9120
|
+
/**
|
|
9121
|
+
* The agent's optional concern category (advisory).
|
|
9122
|
+
*/
|
|
9123
|
+
concern?: (string | null)
|
|
9124
|
+
/**
|
|
9125
|
+
* Hard fence: always `false`. The framing is agent prose, never a
|
|
9126
|
+
* deterministic fallow result, so it never gates or auto-posts.
|
|
9127
|
+
*/
|
|
9128
|
+
deterministic: boolean
|
|
9129
|
+
}
|
|
9130
|
+
/**
|
|
9131
|
+
* One rejected judgment plus the reason it was rejected.
|
|
9132
|
+
*/
|
|
9133
|
+
export interface RejectedJudgment {
|
|
9134
|
+
/**
|
|
9135
|
+
* The `signal_id` the agent cited (fallow never emitted it). Empty when the
|
|
9136
|
+
* judgment cited a `change_anchor` instead.
|
|
9137
|
+
*/
|
|
9138
|
+
signal_id: string
|
|
9139
|
+
/**
|
|
9140
|
+
* The `change_anchor` the agent cited (fallow never emitted it). Empty when
|
|
9141
|
+
* the judgment cited a `signal_id` instead.
|
|
9142
|
+
*/
|
|
9143
|
+
change_anchor: string
|
|
9144
|
+
/**
|
|
9145
|
+
* The rejection reason: `unanchored-signal-id` (cited a signal fallow did
|
|
9146
|
+
* not emit), `unknown-change-anchor` (cited a region fallow did not emit),
|
|
9147
|
+
* or `stale-snapshot` (the tree moved).
|
|
9148
|
+
*/
|
|
9149
|
+
reason: string
|
|
9150
|
+
}
|
|
8442
9151
|
/**
|
|
8443
9152
|
* Single CodeClimate-compatible issue inside [`CodeClimateOutput`].
|
|
8444
9153
|
*/
|