From osprey-rules
Use when validating or reviewing Osprey SML rules. Defines three-layer verification (osprey-cli, proactive checks, convention review) with severity classification. Not triggered on general coding tasks.
How this skill is triggered — by the user, by Claude, or both
Slash command
/osprey-rules:reviewing-osprey-rulesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
This skill defines the three-layer verification methodology for Osprey SML rules.
This skill defines the three-layer verification methodology for Osprey SML rules. You are a read-only reviewer — you analyse and report but NEVER modify files.
Before starting, you should have received:
Run ALL three layers in order. Do not skip layers even if earlier layers pass.
Run the osprey-cli dry-run validator.
Command:
cd {osprey_for_atproto_path} && uv run osprey-cli push-rules {rules_project_path} --dry-run
Classification:
Report each error with:
These are patterns that osprey-cli does NOT catch. Check every rule file in the project for these issues.
Check 2.1: Type mixing in when_all
Examine every Rule(when_all=[...]) block. All items must be the same type:
RegexMatch(...), comparisons (>, <, ==, !=), or/and on bools → boolRule(...) produces RuleT; RuleT or RuleT is also RuleTnot Rule(...) produces RuleT; not bool_val produces boolbool and RuleT items in the same when_all list is a type errorSeverity: Critical (causes runtime type errors that osprey-cli may not catch if a prior error prevents type analysis)
Check 2.2: Hardcoded time values
Search all .sml files for raw numeric time values:
86400 → should be Day604800 → should be Week3600 → should be Hour1800 → should be ThirtyMinute600 → should be TenMinute300 → should be FiveMinute60 → should be MinuteDo NOT flag numbers that appear in non-time contexts (e.g., threshold counts).
Only flag numbers used with window_seconds, expires_after, or similar time
parameters.
Severity: Important
Check 2.3: rules_all= usage
Search for rules_all= in WhenRules() calls. Should always be rules_any=.
Severity: Critical
Check 2.4: JsonData for entity identifiers
Check model files for entity ID variables using JsonData instead of EntityJson.
Entity IDs are variables whose values are used as entity= targets in effects
(LabelAdd, AtprotoLabel, etc.).
Severity: Critical
Check 2.5: Dead rules
Find Rule(...) definitions that are not referenced by any:
WhenRules() block (via rules_any=)when_all listIncrementWindow's when_all listA rule that exists but is never consumed is dead code.
Severity: Important
Check 2.6: (?i) in regex patterns
Search for (?i) inside RegexMatch pattern strings. Should use
case_insensitive=True parameter instead.
Severity: Important
Check rules against the conventions defined in osprey-sml-reference
(references/sml-conventions.md). Load the osprey-sml-reference skill if
you need the full conventions reference.
Check 3.1: Variable naming
_PascalCase (underscore prefix)Rule suffixSeverity: Minor
Check 3.2: Rule descriptions
Rule() descriptions must use f-strings: description=f'...'{Handle} or {UserId} where applicableSeverity: Minor
Check 3.3: No orphaned rules (structural)
Require()d in an index.smlindex.sml must be reachable from the root execution graphSeverity: Important
Check 3.4: Label existence
LabelAdd, AtprotoLabel, etc.) must exist in
config/labels.yamlSeverity: Critical (this is also caught by osprey-cli, but double-check here)
Check 3.5: RegexMatch usage
when_all blocks, don't assign to variables unless reusedcase_insensitive=True parameter, not (?i) in patterntarget= and pattern=Severity: Minor
Check 3.6: IncrementWindow conventions
f'descriptive-name-{UserId}' or f'name-{window}-{UserId}' (kebab-case)window_seconds must use time constantswhen_allSeverity: Minor (naming), Important (duplicates)
Check 3.7: WhenRules conventions
rules_any=, never rules_all= (also checked in Layer 2)WhenRules blockSeverity: Important
Check 3.8: General conventions
or (A or B or C), not function-call or(A, B, C)Severity: Minor (style), Important (correctness)
Structure your report as follows:
## Review Report
### Layer 1: osprey-cli Validation
[Exit code and any errors]
### Layer 2: Proactive Checks
[Issues found, or "No issues found"]
### Layer 3: Convention Review
[Issues found, or "No issues found"]
---
### Critical Issues
1. [file:line] Description (Layer N, Check N.N)
2. ...
### Important Issues
1. [file:line] Description (Layer N, Check N.N)
2. ...
### Minor Issues
1. [file:line] Description (Layer N, Check N.N)
2. ...
---
**Total: X Critical, Y Important, Z Minor**
**Result: PASS / FAIL**
| Rationalization | Reality | Action |
|---|---|---|
| "Minor issues aren't worth reporting" | Minor issues block the gate. All severities must be zero to PASS. | Report every issue, regardless of severity. |
| "osprey-cli passed, so the rules are fine" | osprey-cli catches syntax errors, not logic or convention violations. Layers 2 and 3 exist because osprey-cli is insufficient. | Run all three layers. Always. |
| "I'll just fix this small thing" | You are read-only. Fixing is the debugger's job. | Report the issue. Do not modify files. |
| "This convention seems optional" | All conventions in sml-conventions.md are mandatory for PASS. | Check against every convention. Report violations. |
| "The rule works, so the naming is fine" | Naming conventions prevent maintenance problems. They are not optional. | Report naming violations as Minor severity. |
npx claudepluginhub skywatch-bsky/claude-skills --plugin osprey-rulesProvides UI/UX resources: 50+ styles, color palettes, font pairings, guidelines, charts for web/mobile across React, Next.js, Vue, Svelte, Tailwind, React Native, Flutter. Aids planning, building, reviewing interfaces.
Fetches up-to-date documentation from Context7 for libraries and frameworks like React, Next.js, Prisma. Use for setup questions, API references, and code examples.