Install
$ agentstack add skill-skywatch-bsky-skywatch-agent-skills-fixing-osprey-rules ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Fixing Osprey Rules
This skill provides error categories, diagnosis patterns, and fix workflows for resolving Osprey SML validation errors and reviewer-identified issues.
Input Expectations
You receive a structured issue report from the reviewer. Each issue has:
- File path and line number
- Error description
- Severity (Critical, Important, Minor)
- Layer and check reference
Fix ALL issues in one pass. Do not fix one, re-review, fix another.
1. Understanding osprey-cli Error Output
osprey-cli reports errors in this format:
Error at :::
Key elements:
- File path is relative to the rules project root
- Line and column numbers are 1-indexed
- Error messages describe the validation failure
Exit codes:
- 0: validation passed
- Non-zero: one or more errors found
The --dry-run flag validates without pushing. Always use it during development.
2. Type Mismatches
Error patterns:
incompatible types in assignmentfound multiple different types in list literal
Root cause: Mixing RuleT and bool in when_all lists.
Type rules:
RegexMatch(...), comparisons (>, ` 5, RuleB])
After (all RuleT):
ThresholdRule = Rule(whenall=[SomeBool > 5]) Rule(whenall=[RuleA, ThresholdRule, RuleB])
**Fix option (b):** If most items are `bool`, keep everything as bool:
```sml
# Before (mixed types - wrong):
Rule(when_all=[RuleA, SomeBool, AnotherBool])
# After (all bool - if RuleA can be decomposed):
Rule(when_all=[SomeBool, AnotherBool, SomeOtherBool])
3. Import Cycles
Error: import cycle detected here
Root cause: File A imports file B, which imports file A (directly or transitively).
Fix option (a): Extract shared definitions to a new file imported by both:
# Before: A imports B, B imports A
# After:
# shared.sml ← common definitions
# A imports shared.sml
# B imports shared.sml
Fix option (b): Move the definition causing the cycle to the file that needs it.
Fix option (c): Re-evaluate whether the import is actually needed.
4. Undefined Variables
Error patterns:
unknown identifier ''unknown local variable ''
Root cause (a): Missing import — the file defining the variable is not imported. Fix: Add the missing Import(rules=['path/to/file.sml']).
Root cause (b): Underscore-prefixed variable used cross-file — _PascalCase variables are file-local and cannot be imported. Fix: Rename without underscore prefix if it needs to be imported, or duplicate the definition in the consuming file.
Root cause (c): Typo in variable name. Fix: Correct the spelling to match the definition.
5. Function Call Errors
Error patterns:
unknown function ''unknown keyword argument ''missing keyword argument(s) ''invalid argument type for ''
Fixes:
- Unknown function: Check UDF signatures (from investigator report or reference).
The function may not exist or may have a different name.
- Unknown keyword: Check the function's accepted parameters. Remove or rename.
- Missing keyword: Add the required parameter.
- Invalid type: Check the expected type and convert.
6. Duplicate Definitions
Error: features must be unique across all rule files
Root cause: Same variable name defined in multiple files that are both imported.
Fix:
- Identify which file is the canonical source for the variable
- Remove the duplicate definition from the other file
- Import the canonical source instead
7. Rule Constraint Errors
Error patterns:
rules must be stored in non-local features— Rule assigned to_prefixed variablevariable interpolation in non-format string— description missingfprefix
Fixes:
- Non-local features: Remove
_prefix from Rule variable names. Rules must be
importable (non-local) so they can be used in WhenRules and when_all.
- Non-format string: Add
fprefix to Rule description:description=f'...'
8. Debugging Workflow
When you receive issues to fix, follow this process:
- Categorise issues by root cause. Multiple issues may share the same root cause.
Fix the root cause once rather than fixing each symptom individually.
- Fix in dependency order. If fixing issue A would also fix issue B (cascading
error), fix A first. Cascading errors are common with import cycles and type mismatches.
- Re-validate after EVERY fix. Run
uv run osprey-cli push-rules --dry-run
after each change to confirm the fix worked and didn't introduce new errors. This is a self-check, not the formal gate.
- Handle cascading errors. When osprey-cli reports many errors, often only 1-3
are root causes and the rest are cascading effects. Fix the earliest/deepest error first and re-validate — many other errors may disappear.
- If a fix introduces new errors, revert and try a different approach.
9. Quick Reference Table
| Error | Likely Cause | Fix | |-------|-------------|-----| | incompatible types | Mixed bool/RuleT in whenall | Wrap bools in Rule() or decompose RuleT | | import cycle | Circular imports | Extract shared defs to new file | | unknown identifier | Missing import or prefix | Add import or rename variable | | unknown function | Nonexistent UDF | Check UDF reference | | features must be unique | Duplicate variable names | Remove dupe, import canonical | | non-local features | Rule in prefixed var | Remove prefix | | non-format string | Missing f prefix | Add f to description string |
10. Examples — End-to-End Debugging
Example A: Type Mismatch
Error:
Error at rules/record/post/spam.sml:15:3: found multiple different types in list literal
Diagnosis:
- Open the file, look at line 15
- Find the
when_alllist - Identify which items are
booland which areRuleT - Choose fix option (a) or (b) based on majority type
Fix: Wrap the boolean in a Rule:
_IsNewAccount = Rule(when_all=[AccountAge < Day * 7])
Rule(when_all=[_IsNewAccount, SpamPatternRule])
Example B: Import Cycle
Error:
Error at rules/record/post/index.sml:3:1: import cycle detected here
Diagnosis:
- Trace the import chain from the error file
- Find where the cycle closes
- Identify the shared definition causing the cycle
Fix: Extract shared definition:
# New file: models/shared_post_features.sml
Import(rules=['models/base.sml'])
PostText: str = JsonData(path='$.record.text', required=False)
Example C: Multiple Cascading Errors
Errors:
Error at models/record/post.sml:5:1: unknown identifier 'BaseModel'
Error at rules/record/post/spam.sml:8:1: unknown identifier 'PostText'
Error at rules/record/post/spam.sml:12:3: incompatible types in assignment
Diagnosis:
- First error is the root cause — missing import in model file
- Second error cascades — PostText can't resolve because model failed
- Third error cascades — type inference fails because PostText is unknown
Fix: Fix only the first error (add missing import), re-validate. The other two errors will likely disappear.
Rationalizations to Block
| Rationalization | Reality | Action | | --- | --- | --- | | "I'll fix them one at a time" | Multiple issues may share a root cause. Fixing individually wastes cycles. | Categorise by root cause, fix all in one pass. | | "This error doesn't matter" | All errors block the gate. There is no "doesn't matter." | Fix every issue you received. | | "I'll skip the self-check" | Self-checking confirms your fix worked before the formal review. | Always run osprey-cli after fixing. | | "I'll fix extra issues I found" | You fix what you're given. The reviewer identifies issues, not you. | Only fix the issues in your report. Don't expand scope. | | "The cascading errors are separate issues" | They're almost always symptoms of one root cause. | Fix the deepest error first, re-validate, then check if others resolved. |
Output: Report which issues were fixed and how. The orchestrator will dispatch the reviewer to formally re-verify.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: skywatch-bsky
- Source: skywatch-bsky/skywatch-agent-skills
- License: MIT
- Homepage: https://bsky.app/profile/skywatch.blue
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.