
M12 Lifecycle
Choose RAII, pooling, lazy init, and guard patterns before implementing Rust resources like connections, sessions, and transactions.
Overview
m12-lifecycle is an agent skill for the Build phase that guides Rust resource lifecycle design using RAII, pooling, lazy initialization, and scoped guard patterns.
Install
npx skills add https://github.com/zhanghandong/rust-skills --skill m12-lifecycleWhat is this skill?
- Five lifecycle patterns mapped to implementations: RAII/Drop, lazy init (OnceLock, LazyLock), pools, MutexGuard-style gu
- Decision prompts for resource cost (cheap per-use vs expensive pool vs global singleton), scope (function, request, app-
- Explicit guidance on when Drop is mandatory vs optional explicit close
- Connection pool and session/transaction boundary patterns for production Rust APIs
- 5 lifecycle patterns in the pattern→implementation table
Adoption & trust: 727 installs on skills.sh; 1.2k GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are implementing Rust services and are unsure whether to pool connections, use Drop for cleanup, or how errors should trigger teardown.
Who is it for?
Solo builders designing Rust backends, connection pools, or session-scoped resources who want consistent cleanup semantics.
Skip if: Teams only needing Dockerfile or container deploy steps without writing Rust resource management code.
When should I use this skill?
Use when designing resource lifecycles (RAII, Drop, pools, lazy init, guards, scope-bound transactions).
What do I get? / Deliverables
You pick a documented lifecycle pattern (RAII, pool, lazy singleton, guard, or scoped transaction) with clear ownership and error cleanup before writing the implementation.
- Chosen lifecycle pattern and implementation approach documented in code or design notes
Recommended Skills
Journey fit
Resource lifecycle design happens while shaping backend and systems code, before you ship services that must clean up correctly on errors and under load. Backend subphase covers ownership, Drop, pools (r2d2, deadpool), and scope-bound cleanup—the core of Rust service design.
How it compares
Use for Rust ownership and Drop design—not for Docker packaging or generic web stack cursor rules.
Common Questions / FAQ
Who is m12-lifecycle for?
Rust-focused solo builders and small teams designing APIs, CLIs, or agent backends who need clear create-use-cleanup rules for expensive or scoped resources.
When should I use m12-lifecycle?
Use during Build backend work when defining connections, pools, globals, or transaction boundaries, especially before committing to Drop vs explicit close strategies.
Is m12-lifecycle safe to install?
Review the Security Audits panel on this Prism page; the skill is documentation-only procedural guidance with no declared shell or network permissions in SKILL.md.
SKILL.md
READMESKILL.md - M12 Lifecycle
# Resource Lifecycle > **Layer 2: Design Choices** ## Core Question **When should this resource be created, used, and cleaned up?** Before implementing lifecycle: - What's the resource's scope? - Who owns the cleanup responsibility? - What happens on error? --- ## Lifecycle Pattern → Implementation | Pattern | When | Implementation | |---------|------|----------------| | RAII | Auto cleanup | `Drop` trait | | Lazy init | Deferred creation | `OnceLock`, `LazyLock` | | Pool | Reuse expensive resources | `r2d2`, `deadpool` | | Guard | Scoped access | `MutexGuard` pattern | | Scope | Transaction boundary | Custom struct + Drop | --- ## Thinking Prompt Before designing lifecycle: 1. **What's the resource cost?** - Cheap → create per use - Expensive → pool or cache - Global → lazy singleton 2. **What's the scope?** - Function-local → stack allocation - Request-scoped → passed or extracted - Application-wide → static or Arc 3. **What about errors?** - Cleanup must happen → Drop - Cleanup is optional → explicit close - Cleanup can fail → Result from close --- ## Trace Up ↑ To domain constraints (Layer 3): ``` "How should I manage database connections?" ↑ Ask: What's the connection cost? ↑ Check: domain-* (latency requirements) ↑ Check: Infrastructure (connection limits) ``` | Question | Trace To | Ask | |----------|----------|-----| | Connection pooling | domain-* | What's acceptable latency? | | Resource limits | domain-* | What are infra constraints? | | Transaction scope | domain-* | What must be atomic? | --- ## Trace Down ↓ To implementation (Layer 1): ``` "Need automatic cleanup" ↓ m02-resource: Implement Drop ↓ m01-ownership: Clear owner for cleanup "Need lazy initialization" ↓ m03-mutability: OnceLock for thread-safe ↓ m07-concurrency: LazyLock for sync "Need connection pool" ↓ m07-concurrency: Thread-safe pool ↓ m02-resource: Arc for sharing ``` --- ## Quick Reference | Pattern | Type | Use Case | |---------|------|----------| | RAII | `Drop` trait | Auto cleanup on scope exit | | Lazy Init | `OnceLock`, `LazyLock` | Deferred initialization | | Pool | `r2d2`, `deadpool` | Connection reuse | | Guard | `MutexGuard` | Scoped lock release | | Scope | Custom struct | Transaction boundaries | ## Lifecycle Events | Event | Rust Mechanism | |-------|----------------| | Creation | `new()`, `Default` | | Lazy Init | `OnceLock::get_or_init` | | Usage | `&self`, `&mut self` | | Cleanup | `Drop::drop()` | ## Pattern Templates ### RAII Guard ```rust struct FileGuard { path: PathBuf, _handle: File, } impl Drop for FileGuard { fn drop(&mut self) { // Cleanup: remove temp file let _ = std::fs::remove_file(&self.path); } } ``` ### Lazy Singleton ```rust use std::sync::OnceLock; static CONFIG: OnceLock<Config> = OnceLock::new(); fn get_config() -> &'static Config { CONFIG.get_or_init(|| { Config::load().expect("config required") }) } ``` --- ## Common Errors | Error | Cause | Fix | |-------|-------|-----| | Resource leak | Forgot Drop | Implement Drop or RAII wrapper | | Double free | Manual memory | Let Rust handle | | Use after drop | Dangling reference | Check lifetimes | | E0509 move out of Drop | Moving owned field | `Option::take()` | | Pool exhaustion | Not returned | Ensure Drop returns | --- ## Anti-Patterns | Anti-Pattern | Why Bad | Better | |--------------|---------|--------| | Manual cleanup | Easy to forget | RAII/Drop | | `lazy_static!` | External dep | `std::syn