Rune-stone

How to Use

When given a RUNE spec and its corresponding implementation file, compare them and report every discrepancy.

Input: a RUNE spec (.rune or Markdown) + an implementation file (.py, .ts, .go, etc.). Output: a diff report listing all mismatches.


Comparison Areas

1. SIGNATURE Match

Compare the spec’s SIGNATURE against the actual function declaration.

Check:

Example mismatch:

**SIGNATURE MISMATCH**
- Spec:  `def validate_coupon(code: str, coupons: list[dict], date: str) -> tuple[bool, str]`
- Code:  `def validate_coupon(coupon_code: str, coupon_list: list, current_date: str) -> dict`
- Issues:
  - Parameter renamed: `code` -> `coupon_code`
  - Parameter renamed: `coupons` -> `coupon_list`
  - Parameter renamed: `date` -> `current_date`
  - Type changed: `coupons` lost `[dict]` annotation
  - Return type changed: `tuple[bool, str]` -> `dict`

2. BEHAVIOR Coverage

For each WHEN/THEN rule in the spec, verify the implementation handles it.

Process:

  1. List every BEHAVIOR rule from the spec
  2. Find the corresponding code branch (if/elif/else, match/case, guard clause)
  3. Verify the action matches (return value, exception type, error message)

Check:

Example mismatch:

**BEHAVIOR DRIFT**
- Rule: `WHEN code is empty THEN return (False, "Coupon code cannot be empty")`
- Code: `if not code: raise ValueError("Code required")`
- Issues:
  - Action changed: spec says `return (False, ...)` but code `raises ValueError`
  - Message changed: `"Coupon code cannot be empty"` -> `"Code required"`

3. Error Message Accuracy

Extract all error messages from the implementation and compare against BEHAVIOR.

Check:

4. CONSTRAINTS Enforcement

For each CONSTRAINT in the spec, check if the implementation validates it.

Check:

Example mismatch:

**MISSING CONSTRAINT CHECK**
- Spec CONSTRAINT: `"email: maximum 254 characters (RFC 5321)"`
- Code: No length check found
- Impact: Emails longer than 254 chars will be accepted

5. EDGE_CASES Handling

For each EDGE_CASE in the spec, verify the implementation handles it correctly.

Check:

6. Extra Behavior (not in spec)

Identify behavior in the code that is NOT described in the spec.

Look for:

Example:

**UNDOCUMENTED BEHAVIOR**
- Code has: `if len(email) > 254: return (False, "Email too long")`
- Spec: No BEHAVIOR rule or CONSTRAINT mentions max length
- Action: Add to spec or remove from code

Output Format

## RUNE Diff Report: `<function_name>`

**Spec:** `validate_coupon.rune`
**Code:** `src/coupon.py`

### SIGNATURE
- [MATCH] Function name: `validate_coupon`
- [MATCH] Parameters: `code`, `coupons`, `date`
- [DRIFT] Return type: spec says `tuple[bool, str]`, code returns `tuple[bool, dict | str]`

### BEHAVIOR
| Rule | Status | Detail |
|------|--------|--------|
| WHEN code is empty... | MATCH | Line 12 |
| WHEN code not found... | MATCH | Line 18 |
| WHEN coupon expired... | DRIFT | Message differs: "Coupon has expired" vs "Expired coupon" |
| OTHERWISE... | MATCH | Line 28 |

### ERROR MESSAGES
- [DRIFT] Line 22: `"Expired coupon"` should be `"Coupon has expired"`

### CONSTRAINTS
- [MATCH] code: non-empty string
- [MISSING] code: case-insensitive — code uses exact match instead

### EDGE_CASES
- [MATCH] empty code: handled
- [DRIFT] expires today: spec says "still valid" but code treats it as expired

### UNDOCUMENTED
- Line 8: `if not isinstance(code, str): raise TypeError` — not in spec

### Summary
- **Status:** DRIFT DETECTED
- **Matches:** 7
- **Drifts:** 3 (return type, error message, expiration logic)
- **Missing:** 1 (case-insensitive matching)
- **Undocumented:** 1 (type check)
- **Recommendation:** Update spec to match code, OR fix code to match spec (see details above)

Severity Levels


Rules