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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions