Skip to content

filesystem_unmatched_files should collapse per-directory failures into one line #126

Description

@abegong

Problem

When a whole directory sits outside the include allowlist, filesystem_unmatched_files emits one violation line per file inside it — even though every line has the same message and root cause (the parent directory isn't allowed).

Reproduction

Given .katalyst/bases/local.yaml:

type: filesystem
root: .
filesystemChecks:

  • path: .
    include:
    • "README.md"
    • "ongoing/**"
    • "episodic/**"
      checks:
    • kind: filesystem_unmatched_files

And a project layout with a disallowed sibling directory one-time/ containing 28 files, katalyst check prints 28 nearly-identical lines:

filesystem .: one-time/ai-council-followups-2026/README.md: /: unmatched file (matches no include pattern [README.md, ongoing/, episodic/] and no exclude pattern [])
filesystem .: one-time/ai-council-followups-2026/people/apoorva.md: /: unmatched file (matches no include pattern [...])
filesystem .: one-time/ai-council-followups-2026/people/barry.md: /: unmatched file (matches no include pattern [...])
... (25 more lines)

This drowns the real signal — that one-time/ (the directory) isn't allowed at all — in noise. Adding another disallowed dir with hundreds of files would make the output nearly unreadable.

Suggested behavior

When N files in the same disallowed subtree fail the same check with the same reason, collapse into a single grouped line, e.g.:

filesystem .: one-time/ (28 files): unmatched — matches no include pattern [README.md, ongoing/, episodic/]
filesystem .: sunday-school-scheduling/ (2 files): unmatched — matches no include pattern [...]

Or, more incrementally: identify the shallowest directory whose entire subtree is unmatched and report only that directory, with an optional file count. Files unmatched in an otherwise-allowed directory (e.g. a stray .tmp inside ongoing/) still print individually.

Bonus: verbose mode

Keep the per-file output available behind --verbose / -v for users who want the full list.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions