Validation.Rules (fnord v0.9.29)

View Source

Evaluates and runs project-scoped validation rules after code-modifying tool usage.

This module is the feature-owned context for validation rule matching, command execution, and result summarization. It does not implement the AI.Agent behaviour; instead, higher-level orchestrators call into it at the points where validation rules must be selected and executed.

It determines which validation commands apply to the current set of changed files, expands any glob-like command arguments within the project root, and then runs matching commands without invoking a shell.

Summary

Functions

Returns the current changed files for the project root as project-relative paths. Returns an error if git status cannot be determined, since silent failure in a guardrail feature would mask real problems.

Emits feature-scoped validation debug tracing when FNORD_DEBUG_VALIDATION is truthy.

Emits feature-scoped validation debug tracing when FNORD_DEBUG_VALIDATION is truthy.

Expands and executes one configured validation command from the project root as a direct process invocation.

Expands argv tokens that contain glob syntax into matching project-relative file paths.

Expands a brace expression such as {lib,test}/**/*.ex into a list of plain glob patterns. Handles nested braces like {lib/{src,test},docs}/**/*.ex by finding the innermost brace pair first and expanding outward.

Expands a command string into an executable and argv list suitable for direct execution with System.cmd/3.

Expands a single token. Unmatched patterns are preserved literally so the called program can emit its own diagnostic.

Returns a stable fingerprint for a changed-file set.

Returns true when the glob pattern matches at least one changed file.

Converts a bash-style path glob into a regular expression that matches a project-relative path.

Returns the matching command strings for the given rules and changed files. Duplicate commands are collapsed while preserving first-match order.

Runs validation for the currently selected project against the current working tree changes.

Runs validation for the given project name and root.

Formats a result into a summary suitable for UI output or a system message.

Types

command_result()

@type command_result() :: %{
  command: String.t(),
  status: non_neg_integer(),
  output: String.t()
}

result()

@type result() ::
  {:ok, :no_changes}
  | {:ok, :no_rules, [String.t()], String.t()}
  | {:ok, :no_matches, [String.t()], String.t()}
  | {:ok, [command_result()], String.t()}
  | {:error, command_result(), String.t()}
  | {:error, :discovery_failed}

rule()

@type rule() :: Settings.Validation.rule()

Functions

changed_files(root)

@spec changed_files(String.t()) :: {:ok, [String.t()]} | {:error, :discovery_failed}

Returns the current changed files for the project root as project-relative paths. Returns an error if git status cannot be determined, since silent failure in a guardrail feature would mask real problems.

debug(message)

@spec debug(String.t()) :: :ok

Emits feature-scoped validation debug tracing when FNORD_DEBUG_VALIDATION is truthy.

debug(label, message)

@spec debug(String.t(), String.t()) :: :ok

Emits feature-scoped validation debug tracing when FNORD_DEBUG_VALIDATION is truthy.

execute_validation_command(command, root)

@spec execute_validation_command(String.t(), String.t()) ::
  {:ok, command_result()} | {:error, command_result()}

Expands and executes one configured validation command from the project root as a direct process invocation.

expand_argv(argv, root)

@spec expand_argv([String.t()], String.t()) :: [String.t()]

Expands argv tokens that contain glob syntax into matching project-relative file paths.

expand_braces(pattern)

@spec expand_braces(String.t()) :: [String.t()]

Expands a brace expression such as {lib,test}/**/*.ex into a list of plain glob patterns. Handles nested braces like {lib/{src,test},docs}/**/*.ex by finding the innermost brace pair first and expanding outward.

expand_command(command, root)

@spec expand_command(String.t(), String.t()) :: {String.t(), [String.t()]}

Expands a command string into an executable and argv list suitable for direct execution with System.cmd/3.

expand_token(token, root)

@spec expand_token(String.t(), String.t()) :: [String.t()]

Expands a single token. Unmatched patterns are preserved literally so the called program can emit its own diagnostic.

fingerprint(changed_files)

@spec fingerprint([String.t()]) :: String.t()

Returns a stable fingerprint for a changed-file set.

glob_matches_any_changed_file?(path_glob, changed_files)

@spec glob_matches_any_changed_file?(String.t(), [String.t()]) :: boolean()

Returns true when the glob pattern matches at least one changed file.

glob_to_regex(glob)

@spec glob_to_regex(String.t()) :: Regex.t()

Converts a bash-style path glob into a regular expression that matches a project-relative path.

matching_commands(rules, changed_files)

@spec matching_commands([rule()], [String.t()]) :: [String.t()]

Returns the matching command strings for the given rules and changed files. Duplicate commands are collapsed while preserving first-match order.

run()

@spec run() :: result()

Runs validation for the currently selected project against the current working tree changes.

run(project_name, root)

@spec run(String.t(), String.t()) :: result()

Runs validation for the given project name and root.

This integration-point function discovers changed files, selects the configured commands whose validation rules apply, executes those commands directly from the project root, and returns a structured summary of the outcome.

summarize(arg)

@spec summarize(result()) :: String.t()

Formats a result into a summary suitable for UI output or a system message.