--- name: safety-critical-patterns description: Applies NASA Power of 10 rules for safety-critical verifiable code. Use when auditing financial, medical, or high-reliability system code. alwaysApply: false category: code-quality tags: - safety - defensive-coding - assertions - NASA - robustness - verification tools: [] complexity: intermediate model_hint: standard estimated_tokens: 600 dependencies: - pensive:code-refinement - imbue:review-core - imbue:structured-output --- # Safety-Critical Coding Patterns Guidelines adapted from NASA's Power of 10 rules for safety-critical software. ## When to Apply **Full rigor**: Safety-critical systems, financial transactions, data integrity code **Selective application**: Business logic, API handlers, core algorithms **Light touch**: Scripts, prototypes, non-critical utilities > "Match rigor to consequence" - The real engineering principle ## When NOT To Use - Ordinary application code, where these defensive checks become the bloat that `prefer-invariants-over-fallbacks` targets (use `conserve:code-quality-principles`) ## The 10 Rules (Adapted) ### 1. Restrict Control Flow Avoid `goto`, `setjmp/longjmp`, and **limit recursion**. **Why**: Ensures acyclic call graphs that tools can verify. **Adaptation**: Recursion acceptable with provable termination (tail recursion, bounded depth). ### 2. Fixed Loop Bounds All loops should have verifiable upper bounds. ```python # Good - bound is clear for i in range(min(len(items), MAX_ITEMS)): process(item) # Risky - unbounded while not_done: # When does this end? process_next() ``` **Adaptation**: Document expected bounds; add safety limits on potentially unbounded loops. ### 3. No Dynamic Memory After Initialization Avoid heap allocation in critical paths after startup. **Why**: Prevents allocation failures at runtime. **Adaptation**: Pre-allocate pools; use object reuse patterns in hot paths. ### 4. Function Length ~60 Lines Functions should fit on one screen/page. **Why**: Cognitive limits on comprehension remain valid. **Adaptation**: Flexible for declarative code; strict for complex logic. ### 5. Assertion Density Include defensive assertions documenting expectations. ```python def transfer_funds(from_acct, to_acct, amount): assert from_acct != to_acct, "Cannot transfer to same account" assert amount > 0, "Transfer amount must be positive" assert from_acct.balance >= amount, "Insufficient funds" # ... implementation ``` **Adaptation**: Focus on boundary conditions and invariants, not arbitrary quotas. ### 6. Minimal Variable Scope Declare variables at narrowest possible scope. ```python # Good - scoped tightly for item in items: total = calculate(item) # Only exists in loop results.append(total) # Avoid - unnecessarily broad total = 0 # Why is this outside? for item in items: total = calculate(item) results.append(total) ``` ### 7. Check Return Values and Parameters Validate inputs; never ignore return values. ```python # Good result = parse_config(path) if result is None: raise ConfigError(f"Failed to parse {path}") # Bad parse_config(path) # Ignored return ``` ### 8. Limited Preprocessor/Metaprogramming Restrict macros, decorators, and code generation. **Why**: Makes static analysis possible. **Adaptation**: Document metaprogramming thoroughly; prefer explicit over magic. ### 9. Pointer/Reference Discipline Limit indirection levels; be explicit about ownership. **Adaptation**: Use type hints, avoid deep nesting of optionals, prefer immutable data. ### 10. Enable All Warnings Compile/lint with strictest settings from day one. ```bash # Python ruff check --select=ALL mypy --strict # TypeScript tsc --strict --noImplicitAny ``` ## Rules That May Not Apply | Rule | When to Relax | |------|---------------| | No recursion | Tree traversal, parser combinators with bounded depth | | No dynamic memory | GC languages, short-lived processes | | 60-line functions | Declarative configs, state machines | | No function pointers | Callbacks, event handlers, strategies | ## Integration Reference this skill from: - `pensive:code-refinement` - Clean code and quality dimension - `sanctum:pr-review` - Code quality phase - `/harden` - composed in the hardening pipeline - `/full-review safety-critical` - focused entry point, and an auto-detection row when assertion density is low, loops are unbounded, or recursion lacks a termination proof ## Violation Output Format For each rule violation, report: ``` Rule N: Location: file.py:42 Anchor: `` Issue: Fix: ``` ### Verify Findings Are Grounded (`safety-critical:findings-verified`) Write findings to `.review/findings.json`, run the citation verifier (`Skill(imbue:review-core)` Step 5), and drop or label `UNVERIFIED` any the verifier rejects. ## Exit Criteria - [ ] Each of the 10 rules has an explicit verdict for the target (applies / violated / not applicable), not a silent skip - [ ] Every reported violation cites a concrete `file:line` and the rule number it breaks - [ ] Rules deemed not applicable name the reason (e.g. "no dynamic allocation in this module") rather than being omitted - [ ] Loops flagged under Rule 2 are checked for a statically provable upper bound; unbounded loops are reported - [ ] Recursion flagged under Rule 1 is reported when it lacks a termination argument - [ ] A summary states whether the target is suitable for safety-critical use, or which rules block that judgment - [ ] Every reported violation carries a `Location` + verbatim `Anchor` confirmed by `citation_verifier.py` (exit `0`), or unverified violations were dropped or labeled `UNVERIFIED`. ## Sources - NASA JPL Power of 10 Rules (Gerard Holzmann, 2006) - MISRA C Guidelines - HN discussion insights on practical application