Files
poimen-memory/M4-PROGRESS.md
T

4.0 KiB

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:

mem skill draft --from poimen/infra-root-causes
mem skill draft --from <project>/<query-id> --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:

# 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

    // 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

    // 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/<project>-<query>/ (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:

cargo test --test it_skill_draft
# test result: ok. 7 passed; 0 failed; 0 ignored

Manual command works:

./target/debug/mem skill draft --from test/example
# Creates vault/skills/_drafts/test-example/SKILL.md