Skip to content

Phase 3: Custom recommendation scripts (Rhai + declarative YAML) #143

@Kadajett

Description

@Kadajett

Overview

Enable users to write custom recommendation rules using Rhai scripts or declarative YAML patterns. Rules live in .semfora/rules/ and have access to semfora's index data.

Depends on: #141 (Phase 2)
Parent research: #135

Implementation

1. Add Rhai dependency

In Cargo.toml:

rhai = { version = "1.19", features = ["sync"] }

Rhai is pure Rust, adds ~1MB to binary, sandboxed by default. No filesystem/network access from scripts.

2. Create src/suggest/plugins/mod.rs — Plugin loader

pub struct PluginLoader {
    rhai_engine: rhai::Engine,
}

impl PluginLoader {
    pub fn load_rules_dir(dir: &Path) -> Vec<Box<dyn SuggestRule>> {
        // Scan .semfora/rules/ for .rhai and .yaml files
        // Parse each into a SuggestRule implementation
    }
}

3. Create src/suggest/plugins/rhai_runtime.rs

  • Register custom Rhai types: Symbol, Call, Module (read-only views of index data)
  • Expose query functions: symbols_in_module(name), callers_of(hash), calls_from(hash)
  • Script returns array of recommendation objects

Example Rhai script (.semfora/rules/api-error-handling.rhai):

// Flag API functions without error handling
let results = [];
for sym in symbols_in_module("src.api") {
    let has_error = false;
    for call in sym.calls {
        if call.name.contains("catch") || call.name.contains("error") || call.in_try {
            has_error = true;
            break;
        }
    }
    if !has_error {
        results.push(#{
            id: "api-error-handling",
            title: `${sym.name} has no error handling`,
            confidence: 0.9,
            severity: "warning",
            symbols: [sym.ref],
        });
    }
}
results

4. Create src/suggest/plugins/schema.rs — Declarative YAML rules

Simple pattern-matching rules without scripting:

id: api-error-handling
category: custom
severity: warning
match:
  module_pattern: "src/api/**"
  min_calls: 1
  missing_calls: ["catch", "try", "error"]
message: "Function {symbol} in {module} has no error handling"
confidence: 0.8

Support match conditions: module_pattern, name_pattern, min_complexity, min_calls, missing_calls, has_decorator, is_exported, is_async.

5. Configuration

In semfora.toml:

[suggest.plugins]
rules_dir = ".semfora/rules"    # default
enabled = true

6. Documentation

Create .semfora/rules/README.md template explaining:

  • Available Rhai functions and types
  • YAML schema reference
  • Example rules for common patterns

Testing

  • Test Rhai script loading and execution
  • Test YAML declarative rule parsing
  • Test that malicious Rhai scripts can't access filesystem
  • Test error handling for invalid scripts
  • Integration test with sample rules directory

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