# Profile-Driven Lifecycle Rules Lifecycle planning can now derive its first local rule set from a Markitect-compatible memory profile. ## Retention Rules `LifecycleRuleConfig.from_profile(...)` reads retention rules from: ```json { "retention": { "default": {"stale_after_days": 7, "delete_after_days": 30}, "episode": {"stale_after_days": 3} } } ``` The fixture style is also supported: ```json { "retention": { "conversation": {"stale_after_days": 7, "delete_after_days": 30} } } ``` When a profile has one nested retention rule and no explicit `default`, that rule becomes the default for local planning. This keeps older profile fixtures useful while more specific node-kind rules evolve. ## Phase Transition Rules The first transition rule format lives in profile metadata: ```json { "metadata": { "phase_transitions": [ { "kind": "episode", "from_phase": "fluid", "to_phase": "stabilized", "min_age_days": 7, "reason": "episode old enough to stabilize" } ] } } ``` Transitions into `stabilized` or `rigid` still require review. The rule only creates a dry-run `transition_phase` action. ## Refresh And Compaction Refresh actions are only produced when the profile enables refresh and the caller supplies source digests: ```bash phase-memory graph lifecycle tests/fixtures/memory-graph.json \ --profile tests/fixtures/memory-profile.json \ --refresh-digest event.restart=new ``` Compaction can be requested through `--compact-node` or profile compaction metadata with `node_ids` / `compact_node_ids`. ## Runtime API Use `PhaseMemoryRuntime.plan_lifecycle_with_profile(...)` when callers have a profile and graph envelope. The returned runtime envelope includes: - `dry_run_actions` - `profile_id` - `rule_config` - source digest and compaction parameters