Skip to content

pallaoro/rulespec

Repository files navigation

rulespec

npm license

Manage business rules for AI agents without breaking what already works.

Adding a rule to a system prompt shouldn't risk invalidating the ones that are already there. Inline prompt editing doesn't scale — and other solutions aren't built for business rules.

rulespec treats each rule as an independent, validated unit. Add, edit, or remove one rule via CLI — the rest stay untouched. The output is a structured SKILL.md that any AI agent can load.

Quick start

npx rulespec init --domain "customer support"

npx rulespec add --id refund-policy \
  --rule "Refunds allowed within 30 days for unused items" \
  --context "Customer asks about returns" \
  --intent enforce

npx rulespec add --id escalation \
  --rule "Escalate to human after 2 failed attempts" \
  --context "Automated support cannot resolve" \
  --intent enforce

npx rulespec emit
# → skills/customer-support/SKILL.md

No global install needed — npx downloads and runs it automatically.

Install as an agent skill

# All agents globally
npx skills add pallaoro/rulespec -g -y

# Claude Code only
npx skills add pallaoro/rulespec -g -a claude-code -y

# OpenClaw (via ClawHub)
openclaw skills install rulespec

This installs the rulespec skill into your agent so it knows how to use the CLI when you ask it to create or manage business rules.

How it works

A rulespec file is deliberately simple. Business rules are data, not prose buried in a system prompt:

# rulespec.yaml
schema: rulespec/v1
domain: "invoice processing"

sources:
  - id: invoice
    type: document
    format: pdf
    description: "Incoming vendor invoice"
    schema:
      number: string
      vendor: string
      amount: number
      currency: string

  - id: erp-api
    type: api
    format: json
    description: "ERP vendor lookup"

rules:
  - id: duplicate-check
    rule: "Reject invoices with duplicate invoice numbers"
    context: "Before processing any invoice"
    intent: enforce

  - id: approval-threshold
    rule: "Invoices over $5000 require manager approval"
    context: "After extraction, before posting"
    intent: enforce

  - id: greeting
    rule: "Address the submitter by first name in confirmation messages"
    context: "After processing decision"
    intent: inform

examples:
  - note: "Foreign currency invoice requiring approval"
    input:
      invoice: { number: "INV-1001", vendor: "Acme GmbH", amount: 7200, currency: "EUR" }
    output:
      action: "require-approval"
      approver: "finance-mgr"

  - note: "Duplicate invoice rejection"
    input:
      invoice: { number: "INV-0999", vendor: "Local Supply" }
      existing_invoices: ["INV-0999"]
    output:
      action: "reject"
      reason: "duplicate"

  - note: "PDF invoice extraction"
    input:
      file: "./samples/invoice-1003.pdf"
    output:
      action: "auto-approve"
      vendor: "Office Depot"
      amount: 135

Fields

Rules have four fields:

Field Owner Purpose
id Engineer Unique identifier (kebab-case)
rule Business person The business rule in plain language
context Shared When this rule applies
intent Business person enforce, inform, or suggest

Intent shapes the compiled output:

  • enforce — mandatory. Compiles to **You must follow this rule.**
  • inform — guidance. Neutral language.
  • suggest — recommendation. Compiles to Consider the following:

Sources (optional) describe what data the rules operate on — type, format, schema.

Examples (optional) are input/output golden standards for evaluation. They exist at two levels:

  • Global examples — end-to-end test cases across all rules
  • Per-rule examples — scoped to a single rule

CLI commands

Setup

rulespec init --domain "invoice processing"
rulespec set-domain "customer support"

Rules

rulespec add --id <id> --rule <text> --context <text> --intent <enforce|inform|suggest>
rulespec edit <id> [--rule <text>] [--context <text>] [--intent <type>]
rulespec remove <id>
rulespec list

Sources

rulespec add-source --id <id> --type <document|api|database|message|structured> --description <text> [--format <fmt>]
rulespec remove-source <id>

Examples

# Global examples
rulespec add-example --input '{"amount": 100}' --output '{"action": "approve"}' --note "Small amount"
rulespec add-example --input /path/to/input.json --output /path/to/expected.json
rulespec add-example --input /path/to/invoice.pdf --output '{"vendor": "Acme", "total": 500}'
rulespec remove-example <index>

# Rule-specific examples
rulespec add-rule-example <rule-id> --input '{"days": 5}' --output '{"refund": true}'
rulespec add-rule-example <rule-id> --input /path/to/document.pdf --output '{"extracted": "data"}'
rulespec remove-rule-example <rule-id> <index>

Input/output accepts three formats:

  • Inline JSON'{"key": "val"}'
  • JSON file/path/to/data.json (read and parsed)
  • Any file/path/to/doc.pdf (stored as { file: "/path/to/doc.pdf" })

Find & replace

rulespec replace --old "30 days" --new "60 days"

Safe find-and-replace: validates the result and recompiles all prompts automatically.

Build & emit

rulespec compile [id]                  # Preview compiled prompts
rulespec validate                      # Check file against schema
rulespec emit                          # Generate skills/{domain}/SKILL.md
rulespec emit --include-examples true  # Include examples in output
rulespec emit --outdir <path>          # Custom output directory (default: skills)

All commands accept --file <path> (default: rulespec.yaml).

Output

rulespec emit generates a SKILL.md in the skills directory:

skills/
  invoice-processing/
    SKILL.md
  customer-support/
    SKILL.md

The emitted SKILL.md uses YAML frontmatter for agent discovery and intent tags ([enforce], [inform], [suggest]) that tell the agent how strictly to follow each rule:

---
name: invoice-processing
description: Business rules for invoice processing. 3 rules: Duplicate Check, Approval Threshold, Greeting.
type: rules
schema: rulespec/v1
# Auto-generated by rulespec. Do not edit — changes will be overwritten on next emit.
---

## Rules

### Duplicate Check [enforce]
**You must follow this rule.** Before processing any invoice: Reject invoices with duplicate invoice numbers.

### Approval Threshold [enforce]
**You must follow this rule.** After extraction, before posting: Invoices over $5000 require manager approval.

### Greeting [inform]
After processing decision: Address the submitter by first name in confirmation messages.

Programmatic usage

Use rulespec as a library to inject rules into LLM prompts at runtime:

import { loadRules } from "rulespec";

// Load and compile rules into a markdown string
const rules = await loadRules("rulespec.yaml");

// Inject into your LLM call
const response = await llm.chat({
  system: `You are a support agent.\n\n${rules}`,
  message: userMessage,
});

loadRules() reads the rulespec file and returns the compiled markdown — ready to inject into any system prompt, API call, or workflow step.

npm install rulespec

Design choices

  • Format first, tooling second. The YAML file is the product. The CLI is convenience.
  • One rule, one change. Editing a rule only affects that rule's compiled prompt. No cascading rewrites.
  • Intent shapes output. Same rule, different prompt weight — controlled by one field.
  • Business people own rules, engineers own strategy. Rules are plain language. Compilation is where prompt engineering lives.
  • Sources describe, examples prove. Together they form a complete, evaluable specification.
  • Schema up, data stays down. The spec (rules + source schemas) is safe to share. Examples contain real data and are excluded from output by default.

Why not just edit prompts directly?

You can. It works until:

  • A policy changes and you update 3 of 7 places it appears
  • Two teams edit the same system prompt and one overwrites the other
  • You can't tell which rule a paragraph of prompt corresponds to
  • You want to A/B test one rule change without risking the rest
  • An auditor asks "where is the refund policy enforced in our AI?"

rulespec makes rules traceable, diffable, and independently versionable. git blame shows who changed a rule and when. Examples prove the rules work.

Tech Stack

Layer Technology
Runtime Node.js, TypeScript
Format YAML (rulespec/v1 schema)
Output Markdown (SKILL.md with YAML frontmatter)
Dependencies yaml (single runtime dep)
AI generation Optional — AI SDK peer dep for LLM-assisted prompt compilation

License

MIT

Built by the team behind Clawnify.

About

Business rules as structured data. Compiles into LLM-ready prompts and agent-loadable SKILL.md files.

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors