* fix(#1012): invoke fallow with its real CLI and wire the report normalizer The /gsd-code-review structural pre-pass invoked fallow with flags no published fallow version accepts (--json, --profile, --stdin-files), so it failed on every run and degraded silently per REQ-FALLOW-02 — the feature never delivered on any fallow version. Three compounding defects: 1. Invalid flags. Real fallow audit uses --format json (not --json), -q/--quiet, --changed-since/--base for changed-files scoping (no file-list input), and --max-crap for thresholds. There is no --profile or --stdin-files. 2. Exit-code handling. fallow audit exits 1 when it FINDS issues (verdict=fail), 0 when clean. The pre-pass treated any non-zero exit as a crash and discarded the output — i.e. it threw away exactly the findings it exists to surface. Success is now decided by whether a valid fallow JSON report was produced, not by the exit code. 3. Schema mismatch. normalizeFallowReport parsed a fictional top-level schema (unusedExports/duplicates/circularDependencies) fallow never shipped, and was dead code (the workflow embedded raw JSON; its tests asserted the fictional schema, one even calling a non-existent runFallowAudit and passing vacuously). Fixes: align the invocation to fallow's documented agent-facing pattern; map the profile preset (minimal/standard/strict) to --max-crap (50/30/15); scope phase runs via --changed-since with a repo-scope fallback; rewrite the normalizer to fallow's real schema (dead_code.unused_exports/unused_files/circular_dependencies + duplication.clone_groups) and wire it into the workflow so the reviewer receives normalized findings; replace the fictional-schema fixtures and tests with real-schema ones and delete the vacuous runFallowAudit test. Closes #1012 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * chore(#1012): backfill changeset PR number to 1044 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
48
tests/fixtures/fallow/sample-edge-cases.json
vendored
48
tests/fixtures/fallow/sample-edge-cases.json
vendored
@@ -1,47 +1 @@
|
||||
{
|
||||
"unusedExports": [
|
||||
{
|
||||
"file": "src/café/utils.ts",
|
||||
"symbol": "helperFn",
|
||||
"line": 42
|
||||
}
|
||||
],
|
||||
"duplicates": [
|
||||
{
|
||||
"left": {
|
||||
"file": "src/a.ts",
|
||||
"start": 1,
|
||||
"end": 5
|
||||
},
|
||||
"right": {
|
||||
"file": "src/b.ts",
|
||||
"start": 1,
|
||||
"end": 5
|
||||
},
|
||||
"similarity": 0.0
|
||||
},
|
||||
{
|
||||
"left": {
|
||||
"file": "src/c.ts",
|
||||
"start": 10,
|
||||
"end": 20
|
||||
},
|
||||
"right": {
|
||||
"file": "src/d.ts",
|
||||
"start": 10,
|
||||
"end": 20
|
||||
},
|
||||
"similarity": 1.0
|
||||
}
|
||||
],
|
||||
"circularDependencies": [
|
||||
{
|
||||
"cycle": [
|
||||
"src/x.ts",
|
||||
"src/y.ts",
|
||||
"src/z.ts",
|
||||
"src/x.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{ "schema_version": 3, "version": "2.70.0", "command": "audit", "verdict": "fail", "changed_files_count": 3, "base_ref": "main", "head_sha": "def5678", "elapsed_ms": 88, "summary": { "dead_code_issues": 2, "dead_code_has_errors": true, "complexity_findings": 0, "max_cyclomatic": null, "duplication_clone_groups": 1 }, "attribution": { "gate": "new-only", "dead_code_introduced": 2, "dead_code_inherited": 0, "complexity_introduced": 0, "complexity_inherited": 0, "duplication_introduced": 1, "duplication_inherited": 0 }, "dead_code": { "schema_version": 6, "summary": { "total_issues": 2, "unused_files": 0, "unused_exports": 1, "circular_dependencies": 1 }, "unused_files": [], "unused_exports": [ { "path": "src/café/résumé.ts", "export_name": "naïveHelper", "is_type_only": false, "line": 0, "col": 0, "span_start": 0, "is_re_export": false, "introduced": true, "actions": [] } ], "circular_dependencies": [ { "files": ["src/a.ts", "src/b.ts", "src/c.ts"], "length": 3, "line": 2, "col": 4, "introduced": true, "actions": [] } ] }, "duplication": { "clone_groups": [ { "instances": [ { "file": "src/only-one.ts", "start_line": 5, "end_line": 30, "start_col": 0, "end_col": 1, "fragment": "..." } ] } ], "stats": { "clone_groups": 1 } }, "complexity": { "findings": [] } }
|
||||
|
||||
6
tests/fixtures/fallow/sample-empty.json
vendored
6
tests/fixtures/fallow/sample-empty.json
vendored
@@ -1,5 +1 @@
|
||||
{
|
||||
"unusedExports": [],
|
||||
"duplicates": [],
|
||||
"circularDependencies": []
|
||||
}
|
||||
{ "schema_version": 3, "version": "2.70.0", "command": "audit", "verdict": "pass", "changed_files_count": 0, "base_ref": "main", "head_sha": "0000000", "elapsed_ms": 5, "summary": { "dead_code_issues": 0, "dead_code_has_errors": false, "complexity_findings": 0, "max_cyclomatic": null, "duplication_clone_groups": 0 }, "attribution": { "gate": "new-only", "dead_code_introduced": 0, "dead_code_inherited": 0, "complexity_introduced": 0, "complexity_inherited": 0, "duplication_introduced": 0, "duplication_inherited": 0 }, "dead_code": { "schema_version": 6, "summary": { "total_issues": 0, "unused_files": 0, "unused_exports": 0, "circular_dependencies": 0 }, "unused_files": [], "unused_exports": [], "circular_dependencies": [] }, "duplication": { "clone_groups": [], "stats": { "clone_groups": 0 } }, "complexity": { "findings": [] } }
|
||||
|
||||
34
tests/fixtures/fallow/sample-findings.json
vendored
34
tests/fixtures/fallow/sample-findings.json
vendored
@@ -1,33 +1 @@
|
||||
{
|
||||
"unusedExports": [
|
||||
{
|
||||
"file": "sdk/src/query/commit.ts",
|
||||
"symbol": "commitToSubrepo",
|
||||
"line": 289
|
||||
}
|
||||
],
|
||||
"duplicates": [
|
||||
{
|
||||
"left": {
|
||||
"file": "gsd-core/bin/lib/config-schema.cjs",
|
||||
"start": 14,
|
||||
"end": 22
|
||||
},
|
||||
"right": {
|
||||
"file": "sdk/src/query/config-schema.ts",
|
||||
"start": 9,
|
||||
"end": 17
|
||||
},
|
||||
"similarity": 0.98
|
||||
}
|
||||
],
|
||||
"circularDependencies": [
|
||||
{
|
||||
"cycle": [
|
||||
"src/a.ts",
|
||||
"src/b.ts",
|
||||
"src/a.ts"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
{ "schema_version": 3, "version": "2.70.0", "command": "audit", "verdict": "fail", "changed_files_count": 5, "base_ref": "main", "head_sha": "abc1234", "elapsed_ms": 120, "summary": { "dead_code_issues": 3, "dead_code_has_errors": true, "complexity_findings": 0, "max_cyclomatic": null, "duplication_clone_groups": 1 }, "attribution": { "gate": "new-only", "dead_code_introduced": 3, "dead_code_inherited": 0, "complexity_introduced": 0, "complexity_inherited": 0, "duplication_introduced": 1, "duplication_inherited": 0 }, "dead_code": { "schema_version": 6, "summary": { "total_issues": 3, "unused_files": 1, "unused_exports": 1, "circular_dependencies": 1 }, "unused_files": [ { "path": "src/orphan.ts", "introduced": true, "actions": [] } ], "unused_exports": [ { "path": "sdk/src/query/commit.ts", "export_name": "commitToSubrepo", "is_type_only": false, "line": 289, "col": 16, "span_start": 1234, "is_re_export": false, "introduced": true, "actions": [] } ], "circular_dependencies": [ { "files": ["src/a.ts", "src/b.ts"], "length": 2, "line": 1, "col": 9, "introduced": true, "actions": [] } ] }, "duplication": { "clone_groups": [ { "instances": [ { "file": "gsd-core/bin/lib/config-schema.cjs", "start_line": 14, "end_line": 22, "start_col": 0, "end_col": 1, "fragment": "..." }, { "file": "sdk/src/query/config-schema.ts", "start_line": 9, "end_line": 17, "start_col": 0, "end_col": 1, "fragment": "..." } ] } ], "stats": { "clone_groups": 1 } }, "complexity": { "findings": [] } }
|
||||
|
||||
Reference in New Issue
Block a user