# Lifecycle Stages > **Quick Ref:** Assertions have lifecycle state: Proposed → UnderReview → Approved | Deprecated | Rejected > **Status:** Implemented in `stemedb-core` v0.1.0 > **File:** `crates/stemedb-core/src/types.rs` ## The Problem AI agents can't distinguish proposals from decisions. An RFC saying "we should use ES256" looks the same as an approved policy saying "use ES256." Agents query, get proposals, treat them as truth. ## The Solution ```rust enum LifecycleStage { Proposed, // Idea, RFC, suggestion UnderReview, // Being evaluated Approved, // Accepted as current truth Deprecated, // Was true, now superseded Rejected, // Considered and declined } struct Assertion { // ... existing fields pub lifecycle: LifecycleStage, } ``` ## Query Integration ``` # Only approved patterns (safe for implementation) GET /query?subject=auth/jwt&predicate=algo&lifecycle=approved # All stages (for research/context) GET /query?subject=auth/jwt&predicate=algo&lifecycle=any # Show proposals needing review GET /query?predicate=*&lifecycle=under_review ``` ## State Transitions ``` Proposed → UnderReview → Approved → Deprecated ↘ Rejected ``` Transitions are new assertions, not mutations: ``` POST /assert { "subject": "auth/jwt", "predicate": "signing_algorithm", "object": { "Text": "ES256" }, "lifecycle": "Approved", "parent_hash": "proposal_hash...", # Links to original proposal "signatures": [{ "agent_id": "security_lead", ... }] } ``` ## Lens Interaction | Lens | Lifecycle Behavior | |------|-------------------| | Recency | Returns most recent matching lifecycle filter | | Consensus | Counts votes within lifecycle stage | | Authority | Weights by signer reputation, respects lifecycle | | EpochAware | Filters by epoch AND lifecycle | ## Origin This feature emerged from user research (see `.claude/agents/perspective-*.md`). The Implementation Agent's core need: "If proposed and approved look the same, I can't use this."