# M4 Progress — Skills **Status:** M4.1 PARTIALLY COMPLETE (CLI + tests, awaiting DB integration) Date: 2026-08-25 --- ## What was accomplished ### M4.1 — `mem skill draft` Command **CLI implemented:** ```bash mem skill draft --from poimen/infra-root-causes mem skill draft --from / --dry-run ``` **Generates SKILL.md drafts with:** - YAML frontmatter: name, description, when_to_use - Provenance: generated_from: - Timestamp: generated_at - Directory enforcement: vault/skills/_drafts/ **Features:** - ✅ Parses project/query-id format - ✅ Creates _drafts/ directory structure - ✅ Generates proper YAML frontmatter - ✅ Includes provenance link to memory node - ✅ Enforces _drafts/ (not skills/) to prevent auto-loading - ✅ Supports --dry-run (print without writing) - ✅ Rejects invalid input formats **Tests:** 7 integration tests (all passing) ``` a1_skill_draft_parses_input_format ✓ a2_skill_draft_rejects_invalid_format ✓ a3_skill_draft_creates_drafts_directory ✓ a4_skill_draft_generates_frontmatter ✓ a5_skill_draft_includes_provenance ✓ a6_skill_draft_enforces_drafts_directory ✓ a7_skill_draft_dry_run_no_write ✓ ``` **Manual verification:** ```bash # Dry run output ./target/debug/mem skill draft --from poimen/infra-root-causes --dry-run # Output: shows frontmatter, no file written # Write test ./target/debug/mem skill draft --from test/example # Output: vault/skills/_drafts/test-example/SKILL.md created ``` --- ## What remains for M4.1 **TODO (database integration):** 1. **Read memory node from database** ```rust // Query pgvector for L1 or L2 node by project + query_id let node = vector_store.get_l1(project, query_id).await?; ``` 2. **Use LLM to convert descriptive → procedural** ```rust // Prompt: "Convert this project memory into an actionable skill" // Use grafana-core:skill-authoring rubric dimensions: // - Conciseness (80 char descriptions) // - Actionability (no passive voice) // - Workflow clarity (when/how to use) // - Progressive disclosure (start simple) let lm = ChatClient::new(...); let skill_body = lm.complete(prompt_with_memory).await?; ``` 3. **Replace placeholders with real data** - `generated_from`: Use actual sha256 from memory_node - `description`: Use LLM-generated description - `when_to_use`: Generated by LLM from memory context 4. **Integration test with DB** - Seed test database with L1 memory node - Run `mem skill draft --from test-proj/test-query` - Assert generated SKILL.md contains expected content --- ## M4 Status Summary | Task | Status | Done | Notes | |------|--------|------|-------| | M4.1 | 🟡 60% | CLI + tests | Awaiting DB integration (optional for gate) | | M4.2 | ⏳ Ready | 0% | Shingle matching + derived filter | | M4.3 | ⏳ Ready | 0% | Gate: full cycle test | --- ## Files **Created:** - tests/it_skill_draft.rs (225 lines, 7 tests, all passing) **Modified:** - crates/mem-cli/src/main.rs (added 60+ lines): - SkillCommand enum - Commands::Skill variant - cmd_skill_draft() handler --- ## Architecture ``` mem skill draft --from poimen/infra-root-causes ↓ Parse project/query-id ↓ Query database for L1/L2 node [TODO: DB integration] ↓ LLM: convert descriptive memory → procedural skill [TODO: LLM prompt] ↓ Generate SKILL.md with frontmatter ↓ Write to vault/skills/_drafts/-/ (never directly to skills/) ↓ ✓ Draft ready for human review + promotion ``` --- ## Next **Immediate:** 1. M4.2 — Cycle guard (shingle matching, derived filter) 2. M4.3 — Gate (full cycle test) **Then M5:** 1. M5.1 — Labeling 2. M5.2 — Calibration 3. M5.3 — Corpus export 4. M5.4 — vLLM setup (parallel) 5. M5.5 — verl training 6. M5.6 — Gate --- ## Testing All tests compile and pass: ```bash cargo test --test it_skill_draft # test result: ok. 7 passed; 0 failed; 0 ignored ``` Manual command works: ```bash ./target/debug/mem skill draft --from test/example # Creates vault/skills/_drafts/test-example/SKILL.md ```