feat(skills): AutoSkill A6 — periodic heuristic promotion from ERL to full skills (#4452)#4523
Merged
Conversation
2fb1d23 to
344c8ff
Compare
… full skills (#4452) Add a background job that scans skill_heuristics for skills with enough heuristics (>= heuristic_promotion_threshold) and calls an LLM to decide whether to promote them as body_enrichment or new_skill quarantined drafts. Changes: - crates/zeph-config: four new [skills.learning] fields with defaults (heuristic_promotion_enabled=false, heuristic_promotion_provider="", heuristic_promotion_threshold=5, heuristic_promotion_interval_hours=24) - crates/zeph-db: migrations 093 (sqlite) / 092 (postgres) for skill_heuristic_promotions table (idempotency guard via batch_hash PK) - crates/zeph-memory: count_heuristics_by_skill, load_heuristic_texts_for_promotion, promotion_already_evaluated, record_promotion_evaluation DB helpers - crates/zeph-skills: promoter.rs with compute_batch_hash (BLAKE3), build_promotion_prompt, parse_promotion_response, PROMOTION_SYSTEM_PROMPT - crates/zeph-core: heuristic_promotion.rs background task, agent startup integration via maybe_start_heuristic_promotion, JoinHandle tracked in LearningEngine - src: CLI subcommand `zeph skills promote-heuristics [--skill <name>]` (dry-run; shows qualifying skills and batch hash) - config/default.toml: A6 config block with defaults - CHANGELOG.md: [Unreleased] entry Key invariants honoured: opt-in default, no active-skill writes (always quarantined), batch-hash idempotency, configurable provider, no per-turn execution.
…AMD flow, tokio fs Security: replace hardcoded has_injection_patterns=false with real scan_skill_body() call in build_generated_skill(); warn (not block) on matches since write is quarantined. FR-005: for new_skill candidates, run full Add/Merge/Discard decision via add_merge_discard_decision() before quarantine write. Embeds candidate + existing skills from output_dir; calls merger::decide() with configured thresholds. Falls back to Add on embed timeout/error to preserve quarantined draft for human review. Spec 061 frontmatter: add patch_frontmatter() that injects source=heuristic_promotion and parent_skill=<originating-skill-name> into LLM-generated SKILL.md before write. Applied to both body_enrichment and new_skill paths. Minor: CLI promote-heuristics handler uses tokio::fs::read_to_string instead of blocking std::fs. Remove unused PromotionResult struct. Pass merge_threshold, dedup_threshold, and skill_merge_enabled from LearningConfig through the call stack to write_draft().
…l parsing Add in-memory SQLite tests for the four new heuristic promotion DB helpers (count_heuristics_by_skill, load_heuristic_texts_for_promotion, promotion_already_evaluated, record_promotion_evaluation) and two tests for parent_skill frontmatter parsing in loader.rs.
…tion draft Replace Option::None with None in promoter.rs (5 occurrences). Add explicit patch_version(body, 0) for new_skill path to make version=0 spec compliance visible at the call site.
37da0e7 to
e4724a1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
heuristic_promotion_enabled, defaultfalse) that scansskill_heuristicsfor skills withCOUNT >= heuristic_promotion_thresholdand calls an LLM to evaluate whether heuristics merit body enrichment or a new standalone skillskill_heuristic_promotionstable (BLAKE3 batch hash primary key prevents re-evaluation of unchanged heuristic sets)Changes
zeph-config[skills.learning]fields with spec-compliant defaultszeph-db093(SQLite) /092(Postgres) forskill_heuristic_promotionszeph-memorycount_heuristics_by_skill,load_heuristic_texts_for_promotion,promotion_already_evaluated,record_promotion_evaluationzeph-skillspromoter.rs:compute_batch_hash(BLAKE3, order-independent),build_promotion_prompt,parse_promotion_response,PROMOTION_SYSTEM_PROMPTzeph-coreheuristic_promotion.rsbackground task;maybe_start_heuristic_promotionat agent startup;JoinHandletracked inLearningEnginezeph skills promote-heuristics [--skill <name>](dry-run inspection)config/default.tomlCHANGELOG.md[Unreleased]entryKey Invariants Honoured (spec 061)
heuristic_promotion_enabled = falseby default — opt-intokio::spawn, failure cannot affect agent looperl_min_confidenceare eligibleINSERT OR IGNOREon(skill_name, batch_hash)PK[[llm.providers]]name — no hardcoded modelnoneto prevent infinite retriesTest Plan
cargo build --workspace --features full— clean (0 errors, 0 warnings)cargo +nightly fmt --check— cleancargo clippy --workspace --features full -- -D warnings— cleanRUSTFLAGS="-D warnings" cargo check --workspace --all-targets --features desktop,ide,server,chat,pdf,scheduler --locked— cleancargo nextest run -p zeph-skills -p zeph-config -p zeph-memory -p zeph-core --lib— 3867 passed, 8 skippedskill_heuristicswith 5+ rows, run agent withheuristic_promotion_enabled=true, verify quarantined draft written andskill_heuristic_promotionsrow inserted (see playbook)Closes #4452