--- name: merge-skills description: "Use when book2skill has run on several books and overlapping skills should be merged or consolidated into one skill drawing on both sources. Not for skills that are merely related, or when the source book2skill output is not present." compatibility: Needs about 64k tokens of context; 32k is best effort. Requires the exegesis and skillsaw CLIs and the plain text of every source book. --- # Merge-Skills — Consolidates Overlapping Skills Across Book2skill Outputs ## Mission Two independently distilled skills covering the same methodology are not twice as good — they compete for invocation and dilute each other. This skill detects genuine convergence across book2skill outputs, verifies it against source material to prevent compounding hallucinations, and constructs a single merged skill whose quality exceeds either source alone. **Boundary:** - ✅ Do: Merge skills where two authors independently address the same principle - ✅ Do: Create synthesis skills where two frameworks are genuinely complementary - ❌ Do not: Merge skills that merely rhyme — surface resemblance is not convergence - ❌ Do not: Merge without source text available for verification - ❌ Do not: Run on book2skill outputs that haven't completed Phase 4 ## Core Pipeline ```text Phase 0: Overlap Detection → overlap-candidates.md Phase 1: Convergence Mapping → 5 parallel agents per candidate pair Phase 1.5: Source Verification → r-verified.md, a1-verified.md per candidate Phase 1.5.5: Enhanced Triple Valid. → V1 + V2 + V3 + V4 gate Phase 2: RIA++ Merge Construction → MERGED_SKILL.md per validated pair Phase 3: Cross-Book Zettelkasten → Updated INDEX.md files + cross-book graph Phase 4: Stress Testing → test-prompts.json with prefer_merged tests ``` ## Input Requirements Confirm before proceeding: 1. **Two or more `books//` directories** — each must have completed book2skill through Phase 4 (SKILL.md + test-prompts.json present for all skills) 2. **Source texts available** — EPUB/PDF/TXT for each book, required for Phase 1.5 source verification. Do not proceed without them. 3. **Merge slug** — the output directory name: `books/merged//` 4. **First time?** — recommend running on one candidate pair before bulk ## Output Structure ```text books/merged// ├── MERGE_OVERVIEW.md # Source books, overlap map, rationale ├── INDEX.md # Generated by `exegesis merge-index`; never hand-edit ├── skills-manifest.json # Written by `exegesis verify --merge` ├── candidates/ │ └── overlap-candidates.md # All detected pairs with similarity assessment ├── rejected/ │ ├── .md # Pairs rejected with reason (audit trail) │ └── artifacts/ # A dissolved merge's moved files (Phase 4) ├── source-verification/ │ ├── -r.md # Quote accuracy check results │ └── -a1.md # Case attribution check results ├── / │ ├── SKILL.md # Merged skill (dual provenance); under 500 lines │ └── test-prompts.json # Includes prefer_merged_over_source tests └── dev/ └── / # Development artifacts; never shipped ├── merge-audit.md # Convergence/divergence map, diff of sources (Phase 2) └── test-results.md # Per-case pass/fail with reasoning (Phase 4) ``` **Development artifacts live beside the skill, not inside it.** `` is the root the merged skill is written under, here `books/merged//`. Each merged skill's audit files go to `/dev//merge-audit.md` (Phase 2) and `/dev//test-results.md` (Phase 4), where `` is the merged skill's slug. This keeps a skill directory holding only what ships: promoting a skill copies the skill directory into a plugin and `dev//` into the repository's `dev/`. `test-prompts.json` stays in the skill directory, because it is the test contract `exegesis` and `skillsaw` read. Pair ids take the form `pair-NNN` (`pair-001`, `pair-002`, …). `exegesis merge-index` lists a rejected pair only from a file matching `rejected/pair-*.md`, labelled by its first level-one heading, so a differently named record never appears in INDEX.md and anything else matching that pattern is counted as a rejected pair. ## Execution Flow ### Phase 0 — Overlap Detection See `methodology/01-phase0-overlap-detection.md`. Read every `SKILL.md` from all input `books//` directories. For each cross-book skill pair, assess convergence across three dimensions: - **Core claim** — does the fundamental assertion match? - **Mechanism** — does the *why it works* match? - **Application domain** — does the *when to use it* match? Output three categories to `candidates/overlap-candidates.md`: - **Genuine convergence** — all three dimensions align → proceed to Phase 1 - **Surface resemblance** — only labels/metaphors match → reject immediately - **Complementary** — different mechanisms, same problem space → note for Zettelkasten, do not merge Show overlap map to user before proceeding: "Found N genuine convergence pairs, M surface resemblances (rejected), K complementary pairs (Zettelkasten only)." ### Phase 1 — Convergence Mapping (Parallel Agents) See `methodology/02-phase1-convergence-mapping.md`. For each genuine convergence candidate, spawn 5 agents in parallel: | Agent | Input | Output | | ---------------- | ------------------------- | -------------------------------------------------------------------- | | R-Convergence | Both SKILL.md R sections | Where quotes support identical principle vs. different nuances | | I-Divergence | Both SKILL.md I sections | What each interpretation adds; where they disagree | | A1-Cross-Case | Both SKILL.md A1 sections | Whether cases demonstrate same pattern in different domains | | B-Union | Both SKILL.md B sections | Combined failure map; where books warn about different failure modes | | E-Reconciliation | Both SKILL.md E sections | Where steps agree; where disagreement encodes a conditional | Each agent writes to `candidates/-.md`. If your agent cannot start sub-agents, run the same prompts one after another in this session, writing the same files. Give each prompt a fresh read of its `agents/` file and both source sections rather than the previous agent's output, so the five readings stay independent. ### Phase 1.5 — Source Verification See `methodology/03-phase1.5-source-verification.md`. **This phase is non-negotiable.** Merged skills rest on a convergence claim — that claim must be verified against source text, not just against the already-interpreted SKILL.md files. Skipping this phase risks compounding interpretation errors from both extractions. For each genuine convergence candidate, perform three targeted checks: 1. **R Quote Accuracy** — locate each R-section quote in the source text and confirm it is verbatim or within paraphrase distance. Correct any drift. Write results to `source-verification/-r.md`. Run the deterministic check first (source must be plain text — extract EPUB/PDF first): ```text exegesis quotecheck --source-text , books/// ``` It flags any R quote found in **no** source (`MISS`) — the fabrication guard. A verbatim `MISS` means fabricated or drifted; judging paraphrase distance on the remainder is yours. 2. **A1 Case Attribution** — locate each A1 case study in the source and confirm the problem/methodology/conclusion/result chain is correctly described. Write results to `source-verification/-a1.md`. 3. **V1 Convergence Claim** — verify that both books genuinely address the same principle, not just similar-sounding ones. Read the surrounding context in each source, not just the extracted quote. Confirm or downgrade. Only candidates that pass all three checks proceed to Phase 1.5.5. Downgraded candidates move to `rejected/` with reason `source-verification-failed`. Begin each `source-verification/-{r,a1}.md` with a YAML frontmatter header recording the verdict per source, then the free-form narrative; `exegesis merge-index` reads these headers. Read `references/source-verification-header.md` for the header schema before writing the first one, and use the **same ``** in these headers and in the `## Merge Status` ledger. ### Phase 1.5.5 — Enhanced Triple Validation See `methodology/04-phase1.5.5-enhanced-triple-validation.md`. Apply all four validation checks. A candidate must pass all four to proceed. - **V1 — Convergence is genuine**, confirmed by Phase 1.5, not just similar-sounding. - **V2 — Merged predictive power exceeds either source** on a novel scenario. - **V3 — The synthesis is non-obvious**, not common wisdom both authors felt obliged to state. - **V4 — The merge justifies the consolidation**: the merged A2 is not just the union of both source A2s. Read `references/v1-v4-validation.md` for each check's questions and fail conditions before recording a verdict, and `methodology/04-phase1.5.5-enhanced-triple-validation.md` for the full procedure. Record all four verdicts and reasoning in `candidates/overlap-candidates.md`. ### Phase 2 — RIA++ Merge Construction See `methodology/05-phase2-ria-merge-construction.md`. For each candidate that passed Phase 1.5.5, construct the merged SKILL.md and write its convergence/divergence map to `/dev//merge-audit.md`, outside the skill directory (see Output Structure). Each generated `SKILL.md` stays under 500 lines (agentskills.io's recommendation; `exegesis verify` gates it): move longer material into reference files in the skill directory, and have the body say when to read each one. Each segment has specific guidance for the merge case. Declare the sources in the merged skill's frontmatter, by folder name and separated by spaces: ```yaml metadata: merged-from: repository-interface-in-domain-package update-function-closure-repository ``` The key marks the skill as merged, so `exegesis verify` and `exegesis tests` gate it under the merged composition even in a tree of ordinary skills. It also lets exegesis treat a reference to a source that is no longer in the tree as a reference to this skill. `## Provenance` still carries each source's book, author and note. Read `references/merge-segment-guidance.md` before writing each segment: R takes a dual citation with a convergence note, I a single unified synthesis, A1 one case per book in different domains, A2 a trigger sharper (not broader) than either source, E reconciled steps with explicit conditionals, and B the union of both failure maps plus at least one synthesis-specific failure mode. ### Phase 3 — Cross-Book Zettelkasten See `methodology/06-phase3-zettelkasten-cross-book.md`. 1. For each merged skill, add a `superseded-by` link to both source skills' `## Related Skills` section. Record it in the same call as the ledger entry (see Source Skill Annotation below; flags before the dir): ```text exegesis merge-status append --run --state merged \ --into --link books/// ``` (`--state partial` takes `--excluded "…"` as well.) `--link` writes the **tree-qualified** target `merged//`, which is the only form the attribution gate in the Quality Red Lines can follow back from the merged skill: it drops a bare slug as a sibling reference, and the merged skill then reads `a2: not checked`. Do not also run `exegesis link` for the same edge — it would add a second, bare-slug bullet. The bullet's rationale defaults to "superseded by the merge run"; edit the text after the em dash if you want a better one. **Retirement: a `merged`-state parent stays in the book tree and leaves the market corpus; a `partial` parent stays in both.** Read `references/retirement-policy.md` before publishing, retiring or cataloguing any parent, and before using `partial` for a token remainder. It covers the catalog consequence, why `superseded-by` alone retires nothing, and the `exegesis duplicates` check. 2. Link the merged skill back into both source books with `exegesis link` (e.g. `--kind composes-with` / `--kind contrasts-with` to a related skill in each book). `--rationale ""` is required, and the target is tree-qualified, e.g. `--to /`. 3. Generate `books/merged//INDEX.md` deterministically — **do not hand-write it**: ```text exegesis merge-index books/merged// ``` It reads only the merged tree: each merged skill's `## Provenance` block (the Cross-Book Provenance Table), the `source-verification/*.md` headers (the Source Verification Summary), and `rejected/pair-*.md` (Rejected Pairs). `--check` exits 1 unless the file matches what would be generated byte for byte. **It overwrites the whole file**: a section added by hand is lost on the next run, so keep notes, a cross-book graph or commentary in `MERGE_OVERVIEW.md`. ### Phase 4 — Stress Testing See `methodology/07-phase4-stress-test-merged.md`. Use four test categories (not three): | Type | Count | Purpose | | --------------------------- | ----- | --------------------------------------------------------------- | | `should_trigger` | 3–5 | Core use cases for the merged skill | | `should_not_trigger` | 2–3 | Decoys: scenarios where neither source applies | | `edge_case` | 2–3 | Boundary between merged and source skills | | `prefer_merged_over_source` | 2–3 | Scenarios where merged adds value neither source alone provides | Scaffold and validate the structural composition with the CLI — **do not count by hand**: ```text exegesis tests --merge --scaffold books/merged/// exegesis tests --merge books/merged/// ``` `--merge` enforces the four-category gate (≥3 `should_trigger`, ≥2 `should_not_trigger`, ≥2 `edge_case`, ≥2 `prefer_merged_over_source`) and exits non-zero until it passes. A skill declaring `metadata.merged-from` gets the same gate without the flag, so one run checks a plugin that mixes merged and ordinary skills. Runtime pass-rate scoring stays with darwin. Read `references/phase4-cli.md` before migrating a test file in an older shape. The `prefer_merged_over_source` tests are the unique quality gate for merged skills. The comparison must include a **no-skill baseline arm**, not just the two sources: a merge that beats both sources but loses to invoking no skill at all is a net loss and must dissolve (the ablation discipline — a loaded skill can actively hurt). Runtime pass-rate scoring across the arms stays with darwin; there is no `skillsaw pairwise`. If no scenario can be found where the merged skill outperforms both sources **and** the no-skill baseline, the merge failed V4 and should be dissolved back into two independent skills. Run the deterministic trigger-accuracy check on the merged skill as well — its A2 is supposed to be *sharper* than either source, so make that claim legible: ```text skillsaw activation books/merged/// ``` An `UNRESOLVED` exit means add targets or decoys, not edit the skill; a bound that resolves low or negative means return to Phase 1.5.5 and re-check V4. Read `references/phase4-cli.md` for what the check can and cannot show. Pass criteria: 100% on `should_trigger` and `should_not_trigger`; ≥80% overall. Failure triggers Phase 2 rework — not A2 surface patching. Record each case's pass/fail and reasoning in `/dev//test-results.md`, not in the skill directory. **Lint gate.** Before finalizing, run `exegesis lint` on the merged skill AND on every source skill this run modified (Phase 0 `## Merge status`, Phase 3 `## Related Skills`). Fix every error: - Frontmatter has only spec-allowed keys (`name`, `description`, `tags`, `allowed-tools`, `license`, `compatibility`, `metadata`); `name` equals the folder name. - `metadata.merged-from` lists every source skill once, by valid skill name, and not the merged skill itself. - The merged `SKILL.md` is under 500 lines (agentskills.io's recommendation; `exegesis verify` gates it). Move longer material into reference files the body says when to read. - `description` ≤1024 chars, third person, plain text (no `<...>`/XML). - No `[...](../../…/SKILL.md)` links and no absolute or `candidates/` paths in the body — merge provenance goes in `## Provenance`, related skills as slug text. ## Source Skill Annotation Each source skill receives a `merge_status` entry at the phase where its fate is decided. Write it in a **body `## Merge Status` section** (a fenced `yaml` block), not in frontmatter — `merge_status` is not a spec-allowed frontmatter key and would fail `exegesis lint` on the source skill. The block holds a list so multiple runs append without overwriting prior entries. Do not hand-edit the block — append with the CLI, which validates the vocabulary and per-state required fields and is append-only by construction: ```text exegesis merge-status append --run --state \ [--pair … --into … --reason … --excluded …] books/// ``` (Flags come before the directory — flag parsing stops at the first positional.) For a `merged`/`partial` state, add `--link` to do both Phase-3 annotations in one call: it also appends the `` - superseded-by: `merged//` `` bullet to that skill's `## Related Skills` (idempotent). This is how Phase 3 step 1 records the edge. Validate every ledger under a tree with `exegesis merge-status check `. The schema (states, reason codes, required fields) is exactly the vocabulary that `references/merge-status-ledger.md` lists. Read `references/merge-status-ledger.md` for the block's format, the state and reason vocabularies, and how `merge_status` relates to `related_skills`, before appending an entry by hand or reading one. **Rules:** - Absent `merge_status` means the skill has never been evaluated in any merge run. - Never remove or overwrite an existing entry; only append. - Annotate **both** source skills in a pair, not just the one being discarded. - For `no-candidate`, annotate all source skills that appeared in no pair at all, after all pairs in the run have been classified. ______________________________________________________________________ ## Quality Red Lines Before finalizing, run the whole mechanical gate over the merged tree — every merged skill must pass: ```text exegesis verify --merge --strict --source-book books/,books/ \ books/merged// ``` It checks `MERGE_OVERVIEW.md` presence, per-skill `exegesis lint`, and the merge test gate (`tests --merge`) in one pass, and prints `verify: examined N skill(s)`. `--source-book` adds the A2-sharpness check (Red Line 3) across every merged skill: it finds each merged skill's sources by following the `superseded-by` edges Phase 3 wrote back from the source books, and prints `: a2: N new signal(s) over M source(s)`. `--strict` fails a skill with fewer than 2 (`…, want at least 2`). **Treat `a2: not checked` as a failure even though the run does not fail on it**: it means no source edge resolved to that merged skill — usually a bare-slug `superseded-by` target instead of `merged//` (Phase 3 step 1) — so nothing was compared. Each `--source-book` must be a directory whose immediate subdirectories are skills; a book that nests its skills one level deeper reports `no skills found` and contributes no sources. Validate the source skills' ledgers separately with `exegesis merge-status check`. Only the judgment red lines below (source verification, V1–V4, semantic A2 distinctness, additive value) remain the agent's. 1. **Source verification** — Phase 1.5 must complete for every candidate reaching Phase 2. If source texts are unavailable, stop and write `rejected/.md` reason `source-text-unavailable`. Do not proceed on memory or web search. 2. **All four validations** — V1–V4 must all pass. V4 failure → dissolve. 3. **A2 sharpness gate** — the merged A2 must have ≥2 language signals neither source has. After Phase 3, the `verify --strict --source-book` run above checks it for every merged skill at once. Before Phase 3 has written the edges (the Phase 2 completion gate), check one skill with `exegesis a2check --source-skill books//,books// books/merged///` (prints `n of m A2 signal(s) are new`; `--strict` to fail). Fewer than 2 means return to Phase 1.5.5 and re-evaluate V4. Passing the count is necessary but not sufficient — the signals must also be genuinely, semantically distinct, which is your judgment. 4. **Additive gate** — the merged skill must beat **both sources and a no-skill baseline** on at least 1 `prefer_merged_over_source` scenario in Phase 4. A merge that beats the sources but loses to no skill at all is a net loss. If no such scenario can even be written, auto-dissolve before running tests. 5. **Synthesis-specific B** — at least one failure mode in B Part 3 that applies to the merged skill but not either source alone. Generic "convergence authority trap" boilerplate counts only if it is also instantiated for this specific merge. 6. **`/dev//merge-audit.md` complete** — all sections filled, no placeholder text, divergences documented. Phase 4 diagnostic quality depends on this. ## Source Skill Reuse Policy A source skill that has already been merged into one merged skill **can** be used as a source in a subsequent merge run, with restrictions: - ✅ The original source skill file (`books///SKILL.md`) can be used as input — it retains full provenance and verified content - ✅ The original source EPUB/text is still required for Phase 1.5 verification of the new pair - ❌ Do not use a merged skill as a source for another merge — merged skills are synthesis artifacts; merging them compounds interpretive distance from the original texts - ❌ Do not use the `superseded-by` version of a source skill as the basis for a new merge without reading the original source text again — the superseded skill may carry drift that Phase 1.5 of the original merge corrected but did not write back When a source skill is used in multiple merge runs, note it in each merge's `MERGE_OVERVIEW.md` so the cross-reference is visible. ## Calling Conventions - **Always pilot with one candidate pair** before running bulk — unless user says "bulk". - **Show the overlap map after Phase 0** — user confirms before agents are spawned. - **Surface divergences, not just convergences** — the most useful output of a merge is often the conditional in E that encodes where the two authors disagree. - **Dissolve cleanly if V4 fails** — a failed merge should leave both source skills intact and add a Zettelkasten `composes-with` link between them instead. - **Never merge without source texts** — if source EPUBs are not available, stop and ask. - **Auto-dissolve before Phase 4 if no prefer_merged scenarios exist** — writing tests that will all fail wastes Phase 4 cost. Dissolve when the additive gate fails early. ## Ecosystem Positioning ```text book2skill → distills individual books into atomic skills merge-skills → consolidates overlapping skills across books (this skill) darwin-skill → evolves any skill via test-ratchet ``` Merged skills are darwin-compatible: `test-prompts.json` follows the same format. Feed merged output to darwin with: `darwin evolve books/merged//`