Skip to content

Phase 3a: Custom declarative YAML rules for suggest engine #142

@Kadajett

Description

@Kadajett

Context

Part of the --suggest recommendations engine (see #135). Depends on #137, #138, #140.

What to Build

Declarative YAML rules in .semfora/rules/*.yaml

Users write custom rules without code. The engine interprets them against the index data.

1. Rule schema

name: api-error-handling
group: project-conventions
description: "API handlers must have error handling"
match:
  module: "src.api.*"          # glob pattern on module name
  kind: function               # symbol kind filter
  is_exported: true            # boolean filter
  name_pattern: "handle_*"    # glob on symbol name
condition:
  missing_control_flow: ["try", "catch"]    # must have these CF constructs
  # OR alternatives:
  min_complexity: 10                         # cognitive complexity check
  max_complexity: 25
  has_calls_to: ["log_error", "report_*"]   # must call these
  missing_calls_to: ["validate_input"]       # should call but doesn't
  no_callers: true                           # dead code variant
  min_fan_out: 5                             # too many dependencies
severity: warning
confidence: 0.9
suggestion: "Add try/catch error handling to exported API function {symbol}"

2. src/suggest/plugin.rs — Declarative rule loader

pub struct DeclarativeRule {
    pub name: String,
    pub group: String,
    pub description: String,
    pub match_criteria: MatchCriteria,
    pub conditions: Vec<Condition>,
    pub severity: Severity,
    pub confidence: f64,
    pub suggestion_template: String,
}

impl SuggestRule for DeclarativeRule { ... }
  • Load all .yaml files from .semfora/rules/
  • Parse into DeclarativeRule structs
  • Register with SuggestEngine alongside built-in rules
  • Template variables in suggestion: {symbol}, {file}, {module}, {line}

3. Available match/condition fields

Document which index data is queryable:

  • Symbol fields: name, kind, is_exported, module, file, arity
  • Metrics: cognitive_complexity, cyclomatic_complexity, fan_in, fan_out, loc, nesting_depth
  • Graph: callers_count, has_calls_to, missing_calls_to, no_callers
  • Control flow: has_control_flow, missing_control_flow
  • Arguments: argument_count, has_argument_type

Acceptance Criteria

  • .semfora/rules/*.yaml files are loaded and parsed
  • At least these conditions work: module glob, kind, is_exported, missing_control_flow, min_complexity, no_callers
  • Template variables expand correctly in suggestions
  • Invalid rules produce clear error messages (not panics)
  • semfora suggest --list-rules shows both built-in and custom rules
  • Integration test with a sample custom rule
  • Documentation: what fields are available, with examples

References

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions