{
  "name": "Child Workflow with Return",
  "goal": "A reusable child workflow that takes input via call-workflow and returns a structured result. Terminal step is `return`, not `milestone`.",
  "description": "Pattern 12 (child-workflow-contracts). Mark `context.executionInputConfig.internal: true` so the UI hides the Run button — this workflow is invoked only by orchestrators via `call-workflow`. The return contract is explicit: every field a caller can read is declared in `returnConfig.fields`.",
  "status": "draft",
  "context": {
    "executionInputConfig": {
      "title": "Score Entity (called via orchestrator)",
      "description": "This is a child workflow. Run it from an orchestrator via call-workflow, not by hand.",
      "runCTALabel": "Score",
      "allowRegeneration": false,
      "internal": true,
      "fields": [
        { "name": "entity_id", "label": "Entity ID", "type": "text", "required": true },
        { "name": "entity_url", "label": "Entity URL", "type": "text", "required": true }
      ]
    }
  },
  "steps": [
    {
      "id": "start",
      "type": "trigger",
      "name": "Called by Orchestrator",
      "pipelineStepStartConditions": { "trigger": { "type": "manual" } },
      "next": { "stepId": "enrich" }
    },
    {
      "id": "enrich",
      "type": "aiAction",
      "name": "Enrich Entity",
      "pipelineStepPrompt": {
        "template": "Replace with your real enrichment logic.\n\nEntity: {{input.entity_id}}\nURL: {{input.entity_url}}\n\nReturn the enriched fields the score step will consume.",
        "responseStructure": {
          "enriched": "object — fields the score step needs"
        }
      },
      "creditCost": 6,
      "next": { "stepId": "score" }
    },
    {
      "id": "score",
      "type": "aiAction",
      "name": "Score Entity",
      "pipelineStepPrompt": {
        "template": "Score this entity against the rubric stored in KG text (`kg.read-text` with key `design.scoring-rubric` — load upstream if you need it). Return total_score (0-100), decision (qualify|nurture|reject), and reasoning.\n\nEntity: {{input.entity_id}}\nEnriched: {{steps.enrich.enriched}}",
        "responseStructure": {
          "total_score": "number (0-100)",
          "decision": "string (qualify | nurture | reject)",
          "reasoning": "string"
        }
      },
      "creditCost": 8,
      "next": { "stepId": "return-result" }
    },
    {
      "id": "return-result",
      "type": "return",
      "name": "Return Score to Caller",
      "returnConfig": {
        "source": "executionContent",
        "fields": [
          { "name": "entity_id", "stepId": "start", "field": "entity_id" },
          { "name": "total_score", "stepId": "score", "field": "total_score" },
          { "name": "decision", "stepId": "score", "field": "decision" },
          { "name": "reasoning", "stepId": "score", "field": "reasoning" },
          { "name": "enriched", "stepId": "enrich", "field": "enriched" }
        ]
      }
    }
  ]
}
