Tracks the evolutionary lineage of a skill. ``parent_skill_ids`` may contain multiple parents for DERIVED. FIXED always has exactly one parent (the previous version). IMPORTED / CAPTURED have no parents. ─── generation ───────────────────────────────────────────────── Distance
| 68 | |
| 69 | @dataclass |
| 70 | class SkillLineage: |
| 71 | """Tracks the evolutionary lineage of a skill. |
| 72 | |
| 73 | ``parent_skill_ids`` may contain multiple parents for DERIVED. |
| 74 | FIXED always has exactly one parent (the previous version). |
| 75 | IMPORTED / CAPTURED have no parents. |
| 76 | |
| 77 | ─── generation ───────────────────────────────────────────────── |
| 78 | |
| 79 | Distance from root in the version DAG. Set by the evolution logic |
| 80 | when creating a new skill record: |
| 81 | |
| 82 | - IMPORTED / CAPTURED → ``generation = 0`` (root node) |
| 83 | - FIXED → ``parent.generation + 1`` |
| 84 | - DERIVED → ``max(p.generation for p in parents) + 1`` |
| 85 | |
| 86 | ─── change_summary ───────────────────────────────────────────── |
| 87 | |
| 88 | LLM-generated free-text description of what changed vs. the parent. |
| 89 | Produced by the evolution LLM when creating FIXED or DERIVED skills. |
| 90 | Examples: |
| 91 | - FIXED: "Fixed curl parameter format in step 3" |
| 92 | - DERIVED: "Composed weather + geocoding guides into an |
| 93 | end-to-end location-aware forecast workflow" |
| 94 | - IMPORTED / CAPTURED: typically empty or a brief import note. |
| 95 | |
| 96 | ─── content_diff / content_snapshot ──────────────────────────── |
| 97 | |
| 98 | ``content_snapshot`` stores the **full directory snapshot** at this |
| 99 | version as a ``Dict[str, str]`` mapping relative file paths to their |
| 100 | text content. |
| 101 | |
| 102 | ``content_diff`` stores a combined unified diff (``git diff`` |
| 103 | format) covering **all** files in the skill directory. |
| 104 | Policy by parent count: |
| 105 | |
| 106 | - **0 parents** (IMPORTED / CAPTURED): |
| 107 | add-all diff — every line prefixed with ``+`` |
| 108 | (like ``git diff /dev/null`` for each file). |
| 109 | - **1 parent** (FIXED, or single-parent DERIVED): |
| 110 | normal unified diff between the parent's directory content |
| 111 | and this version's directory content, covering all files. |
| 112 | - **N parents** (multi-parent DERIVED): |
| 113 | ``""`` (empty string). A multi-parent composition is a |
| 114 | creative act, not a patch — per-parent diffs are large and |
| 115 | unhelpful. The composition intent is captured in |
| 116 | ``change_summary`` instead. Individual parent content can |
| 117 | be retrieved via ``parent_skill_ids`` → each parent's |
| 118 | ``content_snapshot``. |
| 119 | """ |
| 120 | |
| 121 | origin: SkillOrigin |
| 122 | generation: int = 0 # Distance from root (see docstring) |
| 123 | parent_skill_ids: List[str] = field(default_factory=list) # [] for IMPORTED / CAPTURED |
| 124 | source_task_id: Optional[str] = None # Task that triggered evolution / capture |
| 125 | change_summary: str = "" # LLM-generated description of changes |
| 126 | content_diff: str = "" # Combined unified diff of all files (empty for multi-parent DERIVED) |
| 127 | content_snapshot: Dict[str, str] = field(default_factory=dict) # {relative_path: content} full directory snapshot |
no outgoing calls
no test coverage detected