---
name: morffy-dynamic-topology-generator
description: >-
  Analyze system architecture narratives and translate them into a valid Morffy
  evolution topology JSON payload. Proactively questions the user to discover
  custom tracking metadata properties and milestone bounds before generating data.
---

# Morffy Evolution Topology Generator

## 1. Skill Objective

Analyze text, transcripts, or PRDs to map out a structural system evolution timeline.

**CRITICAL CRITERIA (The Consultation Loop):**
Do not generate the final JSON immediately. If the user narrative lacks clear milestone stages or explicit tracking attributes, you must stop and ask clarifying questions regarding:

1. **The Properties**: What custom metadata boundaries do they want to track and filter (e.g., `team`, `techStack`, `environment`, `domain`, `vendor`)?
2. **The Milestones**: What are the specific release versions or sequential phases?
3. **The Element Type**: What classification should the `type` caption (the second line under each element's label) convey — e.g. component role (`service`, `datastore`, `queue`), ownership, or layer? If they don't care, leave `type` out and the line renders blank.

## 2. Core Axioms & Structural Rules

- **Milestones**: Sequential integers (`0` = baseline, `1` = MVP, `2` = Phase 2, etc.). Each milestone has a `label` (short name **displayed** on the timeline — ideally 1–2 words, e.g. `Baseline`, `MVP`, `Phase 2`, `v1.0`; long labels are truncated and do not render properly) and a `description` (longer text shown as a **tooltip** on hover). Keep the explanation in `description`, not `label`.
- **Lifespans (`sms` & `ems`)**:
  - `sms` (Start Milestone) must always be less than or equal to `ems` (End Milestone).
  - **Containers**: Children cannot outlive their parents (`child.sms >= parent.sms` and `child.ems <= parent.ems`).
  - **Connectors**: Communication pipelines cannot outlive their endpoints (`line.sms >= max(src.sms, tgt.sms)` and `line.ems <= min(src.ems, tgt.ems)`).
- **Icons**: Each element's `icon` is any [lucide](https://lucide.dev/icons) icon name in kebab-case — pick the one that best fits the component (e.g. `server` for a service, `database` for a datastore, `message-square` for a queue, `globe` for a frontend, `shield` for a gateway, `cloud` for a managed service). Unknown names safely fall back to a generic box, so favor a meaningful icon over a perfect one.
- **Flexible Metadata**: The `metadata` block accommodates any custom properties defined by the user. Property values should be arrays of strings wherever possible to natively support linear striped gradient rendering configurations on the frontend canvas.

## 3. Strict Target JSON Schema

```json
{
  "$schema": "[http://json-schema.org/draft-07/schema#](http://json-schema.org/draft-07/schema#)",
  "title": "MorffyDiagramSchema",
  "type": "object",
  "required": ["diagramName", "milestones", "elements", "connectors"],
  "properties": {
    "diagramName": { "type": "string" },
    "milestones": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "label", "description"],
        "properties": {
          "id": {
            "type": "integer",
            "minimum": 0,
            "description": "Sequential integer; referenced by element/connector sms & ems."
          },
          "label": {
            "type": "string",
            "description": "Short name displayed on the timeline, ideally 1-2 words (e.g. 'Baseline', 'MVP', 'v1.0'). Long labels are truncated in the timeline UI; put detail in 'description'."
          },
          "description": {
            "type": "string",
            "description": "Longer text shown as a tooltip when hovering the milestone."
          }
        }
      }
    },
    "elements": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "label", "icon", "sms", "ems", "metadata"],
        "properties": {
          "id": { "type": "string" },
          "label": { "type": "string" },
          "type": {
            "type": "string",
            "description": "Short free-form caption shown as a second line under the element label (e.g. 'service', 'datastore', 'queue'). Ask the user what classification they want here."
          },
          "icon": {
            "type": "string",
            "description": "Any lucide icon name in kebab-case (e.g. 'server', 'database', 'message-square', 'cloud', 'shield'). Unknown names render as a generic box. Full set: https://lucide.dev/icons"
          },
          "parentId": { "type": ["string", "null"] },
          "sms": { "type": "integer" },
          "ems": { "type": "integer" },
          "metadata": {
            "type": "object",
            "description": "Arbitrary user-defined custom properties for slicing, filtering, and color-coding.",
            "additionalProperties": true
          }
        }
      }
    },
    "connectors": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["id", "sourceId", "targetId", "label", "sms", "ems"],
        "properties": {
          "id": { "type": "string" },
          "sourceId": { "type": "string" },
          "targetId": { "type": "string" },
          "label": { "type": "string" },
          "sms": { "type": "integer" },
          "ems": { "type": "integer" }
        }
      }
    }
  }
}
```
