[task] role = "edit-local" agent-id = "kei-prune-scaffold-w14" [scope] files-whitelist = ["_primitives/_rust/kei-prune/**"] files-denylist = ["_primitives/_rust/Cargo.toml"] [verification] cargo-check-crates = ["kei-prune"] cargo-test-crates = ["kei-prune"] test-count-min = 8 [output] report-fields-required = [ "files-touched", "cargo-check", "cargo-test", ] [body] text = """ Create new primitive `kei-prune` — retire unused agents / primitives based on kei-ledger usage stats. Mirrors biological pruning: mozg забывает то что не активировалось достаточно долго. ## Design 1. Engine-native via kei-entity-store. No new schema (just queries over existing ledger `agents` table). 2. Public API: ```rust pub struct PruneCandidate { id: i64, dna: String, last_used_ts: i64, age_days: i64 } pub fn candidates(conn: &Connection, now: i64, min_idle_days: u32) -> Result, Error>; pub fn mark_retired(conn: &Connection, id: i64, now: i64) -> Result<(), Error>; ``` 3. CLI: - `kei-prune list --idle-days 90` — JSON array of candidates - `kei-prune mark --id 5` — mark retired (sets status='retired', no delete) - `kei-prune stats` — summary: active / idle / retired counts 4. Pure metadata primitive — DOES NOT delete anything. Marks ledger row status='retired'. Downstream tooling (archive/compact) can act on marker. ## Tests (≥8) - candidates_returns_empty_on_fresh_db - candidates_excludes_active_rows - candidates_returns_idle_over_threshold - candidates_respects_min_idle_days - mark_retired_updates_status - mark_retired_idempotent - stats_counts_buckets - retired_rows_excluded_from_candidates ## Constructor Pattern Every file ≤200 LOC, every fn ≤30 LOC. Deps: kei-entity-store path, rusqlite workspace, clap workspace, serde workspace, thiserror workspace. ## IMPORTANT — standalone [workspace] escape hatch Add empty [workspace] table to crate's Cargo.toml (inside your whitelist) so cargo check/test work before orchestrator registers in workspace. Orchestrator will remove on merge. """